'Vase Maker 'by Rich Schafermeyer 'updated 6/7/2008: added ability to twist and curve the mesh in real-time 'Converted to IWB by Brian - 02/02/2023 autodefine "off" const DIK_UP = 0xC8 'UpArrow on arrow keypad const DIK_DOWN = 0xD0 'DownArrow on arrow keypad const DIK_LEFT = 0xCB 'LeftArrow on arrow keypad const DIK_RIGHT = 0xCD 'RightArrow on arrow keypad const DIK_PRIOR = 0xC9 'PgUp on arrow keypad const DIK_NEXT = 0xD1 'PgDn on arrow keypad type rgbacolor def r:float def g:float def b:float def a:float endtype type ry def r:float def y:float def h:float endtype WINDOW winmain def x0,y0,bezdotnum,bezsegments,ringsegments,twist,curve,bxy[10],deltaH:int 'INT dotstate INT dotnumber,rdotnumber 'INT winT,winL,winW,winH def ringradius,profileheight,profileheightindex:float 'FLOAT bottomcenter,topcenter 'INT bitmap 'STRING filename$ string filenametex$,filter$ def hastexture:int def shapemade:int def dirx,diry,dirz,lightintensity:float def screen:C3DScreen def camera1:C3DCamera def scene:C3DObject def shape:C3DMesh def light,light1:C3DLight def material:d3dmaterial def diffusecontrol,emissivecontrol,lightambientcontrol,lightdiffusecontrol:int def diffusecolor,emissivecolor,lightambientcolor,lightdiffusecolor:rgbacolor def numVertices,numIndices:int def numberendfaces,bottomface,topface,vindex,findex:int def indexv,indexf:int 'FLOAT movecameray def pVB,pIB:pointer def meshry[34]:ry def vmat:matrix4 INT run = 1 'set everything up to start initvariables() setupwindows() addcontrols() addcamera() addlight() addscene() changelightcolor() makerandomshape() addmaterial() renderscene() do 'use these commands to rotate object IF keydown(DIK_UP) then changedir(dirx,diry,dirz,1,0,0) IF keydown(DIK_DOWN) then changedir(dirx,diry,dirz,-1,0,0) if keydown(DIK_RIGHT) then changedir(dirx,diry,dirz,0,-1,0) if keydown(DIK_LEFT) then changedir(dirx,diry,dirz,0,1,0) IF keydown(DIK_PRIOR) then changedir(dirx,diry,dirz,0,0,1) IF keydown(DIK_NEXT) then changedir(dirx,diry,dirz,0,0,-1) shape.Rotate(dirx,diry,dirz) renderscene() until (keydown(1)|run=0) scene.Free() screen.CloseScreen() closewindow winmain end sub main(),INT select @MESSAGE case @idclosewindow run = 0 case @idcontrol 'if number of bezier dots changed if (@controlid >= 3) & (@controlid <= 5) bezdotnum=@controlid setfocus winmain drawoutline() endif 'if top or bottom check box changed if (@controlid >= 6) & (@controlid <= 7) setfocus winmain topface=getstate(winmain,6) bottomface=getstate(winmain,7) drawoutline() endif case @idhscroll select @code case @sbthumbpos case @sbthumbtrack setscrollpos winmain,@controlid,@qual case @sblineleft setscrollpos winmain,@controlid,(getscrollpos(winmain,@controlid)-1) case @sblineright setscrollpos winmain,@controlid,(getscrollpos(winmain,@controlid)+1) case @sbpageleft setscrollpos winmain,@controlid,(getscrollpos(winmain,@controlid)-5) case @sbpageright setscrollpos winmain,@controlid,(getscrollpos(winmain,@controlid)+5) endselect bezsegments = getscrollpos(winmain,1) setcontroltext winmain,2,str$(bezsegments) ringsegments = getscrollpos(winmain,8) setcontroltext winmain,9,str$(ringsegments) twist= getscrollpos(winmain,10)-360 setcontroltext winmain,11,str$(twist) curve= getscrollpos(winmain,12)-180 setcontroltext winmain,13,str$(curve) drawoutline() case @idchar if (@code = asc("Q")) | (@code = asc("q")) then run = 0 replaceobject() case @idlbuttondn checkfordot() case @idrbuttondn bxy[rdotnumber - 1]=@mousex bxy[rdotnumber]=@mousey drawoutline() case @idlbuttonup dotnumber = 0 case @idmousemove if dotnumber > 0 bxy[dotnumber - 1]=@mousex bxy[dotnumber]=@mousey drawoutline() endif case @idmenupick select @menunum case 1 makerandomshape() case 2 showabout() case 3 run = 0 case 4 saveobject() case 21:'add texture hastexture=0 addtexture() case 22:'remove texture hastexture=0 filenametex$="" shape.Free() shapemade=2 addobject() addmaterial() renderscene() case 23:'reset twist, curve and camera twist=0 setscrollpos winmain,10,twist+360 setcontroltext winmain,11,str$(twist) curve=0 setscrollpos winmain,12,curve+180 setcontroltext winmain,13,str$(curve) changedir(0,0,0,0,0,0) drawoutline() endselect endselect return 0 endsub sub drawoutline() def scw,sch:int getscreensize scw,sch rect winmain,0,0,scw,sch,rgb(255,255,255),rgb(255,255,255) frontpen winmain,rgb(200,200,200) 'draw grey guide lines move winmain,x0,bxy[9] lineto winmain,x0,bxy[1] frontpen winmain,rgb(0,0,0) if bottomface=1 lineto winmain,bxy[0],bxy[1] lineto winmain,2*x0-bxy[0],bxy[1] endif 'draw right side bezier(bezdotnum,bezsegments,bxy,1) 'invert array to draw left side bxy[0]=(2*x0-bxy[0]) bxy[2]=(2*x0-bxy[2]) bxy[4]=(2*x0-bxy[4]) bxy[6]=(2*x0-bxy[6]) bxy[8]=(2*x0-bxy[8]) bezier(bezdotnum,bezsegments,bxy,0) 'restore array bxy[0]=(2*x0-bxy[0]) bxy[2]=(2*x0-bxy[2]) bxy[4]=(2*x0-bxy[4]) bxy[6]=(2*x0-bxy[6]) bxy[8]=(2*x0-bxy[8]) deltaH=bxy[9]-bxy[1] if topface=1 move winmain,bxy[8],bxy[9] lineto winmain,bxy[8],bxy[9] lineto winmain,2*x0-bxy[8],bxy[9] endif addobject() endsub sub makerandomshape() bxy[0]=x0+rnd(200),y0+150,x0+rnd(200),y0+50+rnd(100),x0+rnd(200),y0-50+rnd(100),x0+rnd(200),y0-150+rnd(100),x0+rnd(200),y0-150 drawoutline() endsub sub bezier(bezdotnum:int,bezsegments:int,bxy[10]:int,drawdots:int) 'bezier curve: bezdotnum = number of dots that make curve (2-5), bezsegments = number of straight lines that make up curve, 'bxy: array of x-y pairs that define control dot location def incr,i,i1,i2,i3,i4,x,y,reductionfactor:float def j,k:int incr=1/flt(bezsegments) i=0 k=0 reductionfactor=0.2 move winmain,bxy[0],bxy[1] ringradius=bxy[0]-x0 profileheight=0 profileheightindex=bxy[9]+0.5*(bxy[0]-bxy[9]) 'gosub makeringvertices setlinestyle winmain,@lssolid,3 for j = 0 to bezsegments i1 = 1 - i i2 = (1 - i) * i1 i3 = (1 - i) * i2 i4 = (1 - i) * i3 select bezdotnum case 2 x=bxy[0]*i1+bxy[8]*i y=bxy[1]*i1+bxy[9]*i case 3 x=bxy[0]*i2+bxy[4]*2*i*i1+bxy[8]*i*i y=bxy[1]*i2+bxy[5]*2*i*i1+bxy[9]*i*i case 4 x=bxy[0]*i3+bxy[2]*3*i*i2+bxy[6]*3*i*i*i1+bxy[8]*i^3 y=bxy[1]*i3+bxy[3]*3*i*i2+bxy[7]*3*i*i*i1+bxy[9]*i^3 case 5 x=bxy[0]*i4+bxy[2]*4*i*i3+bxy[4]*6*i*i*i2 x=x+bxy[6]*4*i^3*i1+bxy[8]*i^4 y=bxy[1]*i4+bxy[3]*4*i*i3+bxy[5]*6*i*i*i2 y=y+bxy[7]*4*i^3*i1+bxy[9]*i^4 endselect 'draw line segment if k=0 frontpen winmain,rgb(0,0,0) k=1 else frontpen winmain,rgb(0,200,200) k=0 endif lineto winmain,x,y 'capture radius and height data for object ringradius=x - x0 profileheight=profileheightindex-y meshry[j].r=reductionfactor*ringradius meshry[j].y=reductionfactor*(y0-y) if j=0 meshry[j].h=0 else meshry[j].h=meshry[j-1].h endif i = i + incr next j 'draw squares at start and end, open circles at control points if drawdots = 1 rect winmain,bxy[0]-3,bxy[1]-3,6,6,rgb(255,0,0),rgb(255,0,0) move winmain,bxy[0]+9,bxy[1]-9 print winmain,"Bottom" rect winmain,bxy[8]-3,bxy[9]-3,6,6,rgb(255,0,0),rgb(255,0,0) move winmain,bxy[8]+9,bxy[9]-9 print winmain,"Top" select bezdotnum case 3 circle winmain,bxy[4],bxy[5],3,rgb(255,0,0) case 4 circle winmain,bxy[2],bxy[3],3,rgb(0,255,0) circle winmain,bxy[6],bxy[7],3,rgb(0,0,255) case 5 circle winmain,bxy[2],bxy[3],3,rgb(0,255,0) move winmain,bxy[2]+9,bxy[3]-9 print winmain,"3" circle winmain,bxy[4],bxy[5],3,rgb(255,0,0) move winmain,bxy[4]+9,bxy[5]-9 print winmain,"2" circle winmain,bxy[6],bxy[7],3,rgb(0,0,255) move winmain,bxy[6]+9,bxy[7]-9 print winmain,"1" endselect endif endsub sub checkfordot() def i:int dotnumber = 0 for i=0 to 8 step 2 if (@mousex > (bxy[i]-4)) & (@mousex < (bxy[i]+4)) & (@mousey > (bxy[i+1]-4)) & (@mousey < (bxy[i+1]+4)) dotnumber = i + 1 rdotnumber = i + 1 endif next i endsub sub showabout() messagebox winmain,"Vase Maker by Rich Schafermeyer 2005-2008","About",64 endsub sub initvariables() 'set center x0=525 y0=325 'initialize starting variables filter$ = "JPEG (*.jpg)|*.jpg|GIF (*.gif)|*.gif|BMP (*.bmp)|*.bmp|All Files (*.*)|*.*||" bxy[0]=x0-200,y0,x0-150+rnd(200),y0-200+rnd(400),x0-100+rnd(200),y0-200+rnd(400),x0+50+rnd(200),y0-200+rnd(400),x0+200,y0 bezdotnum=5 bezsegments=16 rdotnumber=1 ringsegments=4 shapemade=0 diffusecontrol=rgb(100,255,100) diffusecolor=convertcolor(diffusecontrol) emissivecontrol=rgb(75,75,75) emissivecolor=convertcolor(emissivecontrol) lightambientcontrol=rgb(255,255,255) lightambientcolor=convertcolor(lightambientcontrol) lightdiffusecontrol=rgb(255,255,255) lightdiffusecolor=convertcolor(lightdiffusecontrol) lightintensity=100 numberendfaces=2 bottomface=1 topface=0 vindex=0 findex=0 twist=0 curve=0 endsub sub setupwindows() 'make main window OpenWindow winmain,0,0,800,600,@minbox|@maxbox|@size|@noautodraw,0,"Vase Maker",&main centerwindow winmain 'add menu BeginMenu winmain MenuTitle "&File" MenuItem "&New",0,1 MenuItem "&Save",0,4 SEPARATOR MenuItem "&About",0,2 SEPARATOR MenuItem "&Quit",0,3 EndMenu BeginInsertMenu winmain,1 MenuTitle "&Texture" MenuItem "Load &Texture",0,21 MenuItem "&Remove Texture",0,22 EndMenu BeginInsertMenu winmain,2 MenuTitle "&Reset" MenuItem "Reset Curve, Twist && Camera",0,23 EndMenu 'make 3D preview window screen.CreateWindowed(4,262,300,280,@nocaption,"3D Preview",winmain,TRUE) endsub sub addcontrols() control winmain,@static,"",6,5,500,20,0x50008000,101 setcontroltext winmain,101,"Hit any key to randomize control dots. Or left-click on a dot and drag" setcontrolcolor winmain,101,rgb(0,0,0),rgb(255,255,255) control winmain,@static,"",6,25,500,20,0x50008000,102 setcontroltext winmain,102,"Or left-click on a dot, then right-click to move that dot to a new position" setcontrolcolor winmain,102,rgb(0,0,0),rgb(255,255,255) control winmain,@RadioButton,"3 Dot Bezier",6,51,120,20,0x50000009,3 control winmain,@RadioButton,"4 Dot Bezier",6,74,120,20,0x50000009,4 control winmain,@RadioButton,"5 Dot Bezier",6,97,120,20,0x50000009,5 control winmain,@CheckBox,"Show Top Face",150,51,132,20,0x50000003,6 control winmain,@CheckBox,"Show Bottom Face",150,74,152,20,0x50000003,7 control winmain,@static,"",6,135,300,20,0x50008000,103 setcontroltext winmain,103,"Set Number of Line Segments in Bezier Curve:" setcontrolcolor winmain,103,rgb(0,0,0),rgb(255,255,255) control winmain,@ScrollBar,"",6,160,101,16,0x50000000,1 control winmain,@Edit,"Edit1",130,159,70,20,0x50800800,2 control winmain,@static,"",6,190,300,20,0x50008000,104 setcontroltext winmain,104,"Set Number of Polygons in Cross Section:" setcontrolcolor winmain,104,rgb(0,0,0),rgb(255,255,255) control winmain,@ScrollBar,"",6,215,101,16,0x50000000,8 control winmain,@Edit,"Edit2",130,214,70,20,0x50800800,9 control winmain,@static,"",355,50,300,20,0x50008000,106 setcontroltext winmain,106,"Set Twist:" setcontrolcolor winmain,106,rgb(0,0,0),rgb(255,255,255) control winmain,@ScrollBar,"",355,75,101,16,0x50000000,10 control winmain,@Edit,"Edit2",465,74,70,20,0x50800800,11 control winmain,@static,"",575,50,300,20,0x50008000,107 setcontroltext winmain,107,"Set Curve:" setcontrolcolor winmain,107,rgb(0,0,0),rgb(255,255,255) control winmain,@ScrollBar,"",575,75,101,16,0x50000000,12 control winmain,@Edit,"Edit2",685,74,70,20,0x50800800,13 control winmain,@static,"",0,245,300,20,0x50008000,105 setcontroltext winmain,105," Use arrow keys to rotate object in 3D Preview" setcontrolcolor winmain,105,rgb(0,0,0),rgb(255,255,255) 'control winmain,@Button,"Reset Camera",310,520,120,20,0x50000000,10 setcontrolcolor winmain,3,0,rgb(255,255,255) setcontrolcolor winmain,4,0,rgb(255,255,255) setcontrolcolor winmain,5,0,rgb(255,255,255) setcontrolcolor winmain,6,0,rgb(255,255,255) setcontrolcolor winmain,7,0,rgb(255,255,255) setscrollrange winmain,1,1,32 setscrollpos winmain,1,bezsegments setcontroltext winmain,2,str$(bezsegments) setscrollrange winmain,8,3,40 setscrollpos winmain,8,ringsegments setcontroltext winmain,9,str$(ringsegments) setscrollrange winmain,10,0,720 setscrollpos winmain,10,twist+360 setcontroltext winmain,11,str$(twist) setscrollrange winmain,12,0,360 setscrollpos winmain,12,curve+180 setcontroltext winmain,13,str$(curve) setstate winmain,5,1 setstate winmain,6,topface setstate winmain,7,bottomface endsub sub addcamera() camera1.Create(screen) camera1.Position(0,0,-130) camera1.Orient(0,0,1,0,1,0) camera1.SetBackPlane(1000) endsub sub addscene() scene.CreateScene(screen) scene.AddChild(light) endsub sub addlight() light.Create(screen,LIGHT_POINT,1) light.Position(0,20,-150) light.SetAttenuation(0,1/200.0,0) light.SetSpecular(.5,.5,.5,1) light.SetAmbient(.4,.4,.4,1) light.SetRange(2000) endsub sub changelightcolor() light.SetAttenuation(0,1/lightintensity,0) light.SetAmbient(lightambientcolor.r,lightambientcolor.g,lightambientcolor.b,1.0) light.SetDiffuse(lightdiffusecolor.r,lightdiffusecolor.g,lightdiffusecolor.b,1.0) endsub sub addmaterial() material.diffuse.r = diffusecolor.r: 'red material.diffuse.g = diffusecolor.g: 'green material.diffuse.b = diffusecolor.b: 'blue material.diffuse.a = diffusecolor.a material.emissive.r = emissivecolor.r material.emissive.g = emissivecolor.g material.emissive.b = emissivecolor.b material.emissive.a = emissivecolor.a shape.SetMaterial(material) shape.UseVertexColor(false) shape.EnableLighting(true) Endsub sub addtexture() if hastexture=0 then filenametex$ = filerequest("Load Bitmap",winmain,1,filter$,"bmp") if filenametex$<> "" shape.LoadTexture(0,filenametex$,0) hastexture = 1 endif endsub sub renderscene() screen.Clear(RGBA(0,0,100,100)): 'sets dx9 screen background color screen.BeginScene(camera1) scene.Draw(): 'renders scene and all objects which are children of scene screen.RenderScene() endsub sub changedir(x:float,y:float,z:float,xincrement:float,yincrement:float,zincrement:float) 'used to rotate object def amount:float amount=0.05: 'changes speed of object rotation x=x+xincrement*amount y=y+yincrement*amount z=z+zincrement*amount dirx=x diry=y dirz=z endsub sub convertcolor(colorin:int),rgbacolor 'used to convert rgb color from colorequest into rgba color def colorout:rgbacolor def r,g,b:int r = (colorin & 0x0000ff) g = (colorin & 0x00ff00) / 256 b = (colorin & 0xff0000) / 65536 colorout.r=flt(r)/255f colorout.g=flt(g)/255f colorout.b=flt(b)/255f colorout.a=0.5f return colorout endsub sub calculateobjectheight() def i:int def x,y,h,length:float 'add up lengths of all faces and rings length=0 if bottomface=1 length=meshry[0].r meshry[0].h=length endif for i=1 to bezsegments x=meshry[i].r-meshry[i-1].r y=meshry[i].y-meshry[i-1].y h=sqrt(x*x+y*y) length=length+h meshry[i].h=length next i if topface=1 x=meshry[bezsegments].r y=meshry[bezsegments+1].y-meshry[bezsegments].y h=sqrt(x*x+y*y) length=length+h meshry[i].h=length endif 'normalize length to one for i=0 to bezsegments+1 meshry[i].h =meshry[i].h/length next i endsub sub addobject() def i:int 'def pRet:pointer: NEEDED?? 'setup numVertices and numIndices to match number of rings numVertices=(ringsegments+1)*(bezsegments+1)+(bottomface+topface)*ringsegments numIndices=(bottomface+topface)*ringsegments*3*2+ringsegments*3*2*2*bezsegments calculateobjectheight() 'if mesh already exists, reallocate it so texture remains attached if shapemade=1 shape.ReallocateMesh(numVertices, numIndices,D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1) else shape.CreateMesh(screen,numVertices,numIndices,D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1) endif 'lock the buffers pVB=shape.LockVertexBuffer() pIB=shape.LockIndexBuffer() indexv=0:indexf=0 'step 1 if bottomface=1 addfacecenterpoint(0,0,meshry[0].y) indexv=indexv+ringsegments endif 'step 2 addringvertices(0,indexv,meshry[0].r,meshry[0].y,0,0,0) indexv=indexv+ringsegments+1 'step 3 if bottomface=1 then makebottomface(indexv-ringsegments-1,indexv-ringsegments*2-1) for i=1 to bezsegments 'step 4 addringvertices(i,indexv,meshry[i].r,meshry[i].y,flt(i)*1.5,0,0) indexv=indexv+ringsegments+1 'step 5 makeringfaces(indexv-ringsegments-1,indexv-ringsegments*2-2) next i if topface=1 addfacecenterpoint(bezsegments,indexv,meshry[bezsegments].y) maketopface(indexv,indexv-ringsegments-1) endif 'unlock the buffers shape.UnlockIndexBuffer() shape.UnlockVertexBuffer() shape.SetVisible(true) if shapemade=0 then scene.AddChild(shape) shapemade=1 renderscene() endsub sub replaceobject() makerandomshape() addobject() addmaterial() renderscene() endsub sub addfacecenterpoint(height:int,index:int,ry:float) def i:int def heightmax:float heightmax=meshry[bezsegments].y-meshry[0].y MatrixIdentity(vmat) MatrixTranslation(vmat,0,ry,0) MatrixRotation(vmat,0,0,3.14159/180*flt(curve)*((meshry[height].y-meshry[0].y)/heightmax)) MatrixRotation(vmat,0,3.14159/180*flt(twist)*((meshry[height].y-meshry[0].y)/heightmax),0) 'need to add multiple copies at same position but with different texCoords for texture mapping for i=0 to ringsegments-1 #pVB[index+i].position.x=vmat.m[0,3] #pVB[index+i].position.y=vmat.m[1,3] #pVB[index+i].position.z=vmat.m[2,3] #pVB[index+i].diffuseColor = RGBA(255,255,255,255) #pVB[index+i].normal = Vec3Normalize(#pVB[index].position) #pVB[index+i].texCoords.x = 1.0-1.0/(2.0*flt(ringsegments))-flt(i)/flt(ringsegments) if index=0 then #pVB[index+i].texCoords.y = 1.0 else #pVB[index+i].texCoords.y = 0.0 endif next i endsub sub addringvertices(height:int,index:int,radius:float,ry:float,dx:float,dy:float,dz:float) def i:int def ang,rx,rz,heightmax:float ang=360f/ringsegments heightmax=meshry[bezsegments].y-meshry[0].y for i=0 to ringsegments rx=radius*cos(i*ang*3.14159/180f) rz=radius*sin(i*ang*3.14159/180f) MatrixIdentity(vmat) MatrixTranslation(vmat,rx,ry,rz) MatrixRotation(vmat,0,0,3.14159/180*flt(curve)*((meshry[height].y-meshry[0].y)/heightmax)) MatrixRotation(vmat,0,3.14159/180*flt(twist)*((meshry[height].y-meshry[0].y)/heightmax),0) #pVB[index+i].position.x=vmat.m[0,3] #pVB[index+i].position.y=vmat.m[1,3] #pVB[index+i].position.z=vmat.m[2,3] #pVB[index+i].diffuseColor = RGBA(255,255,255,255) #pVB[index+i].normal = Vec3Normalize(#pVB[index+i].position) #pVB[index+i].texCoords.x = 1.0-flt(i)/flt(ringsegments) #pVB[index+i].texCoords.y = 1.0-((meshry[height].y-meshry[0].y)/heightmax) next i Endsub sub makebottomface(index:int,indexold:int) def i:int for i=0 to ringsegments-1 #pIB[indexf] = indexold+i #pIB[indexf+1] = index+i #pIB[indexf+2] = index+i+1 #pIB[indexf+3] = indexold+i #pIB[indexf+4] = index+i+1 #pIB[indexf+5] = index+i indexf+=6 next i endsub sub makeringfaces(index:int,indexold:int) def i:int for i=0 to ringsegments-1 #pIB[indexf] = index+i #pIB[indexf+1] = index+i+1 #pIB[indexf+2] = indexold+i #pIB[indexf+3] = index+i+1 #pIB[indexf+4] = indexold+i+1 #pIB[indexf+5] = indexold+i indexf+=6 #pIB[indexf] = index+i #pIB[indexf+1] = indexold+i #pIB[indexf+2] = index+i+1 #pIB[indexf+3] = index+i+1 #pIB[indexf+4] = indexold+i #pIB[indexf+5] = indexold+i+1 indexf+=6 next i endsub sub maketopface(index:int,indexold:int) def i:int for i=0 to ringsegments-1 #pIB[indexf] = index+i #pIB[indexf+1] = indexold+i #pIB[indexf+2] = indexold+i+1 #pIB[indexf+3] = index+i #pIB[indexf+4] = indexold+i+1 #pIB[indexf+5] = indexold+i indexf+=6 next i endsub sub saveobject() def i:int def x,y,z:float def myfile:file def filter$,filename$:string filter$ = "Obj Files (*.obj)|*.obj|All Files (*.*)|*.*||" filename$ = filerequest("Save Object in OBJ Format",winmain,0,filter$,"obj") if len(filename$)=0 then return if (openfile(myfile,filename$,"W")=0) setprecision 5 'write out x, y, z position for each vertice for i=0 to numVertices-1 x=#pVB[i].position.x y=#pVB[i].position.y z=#pVB[i].position.z write myfile,"v "+str$(x)+" "+str$(y)+" "+str$(z) next i 'write out texture coordinates for each vertice for i=0 to numVertices-1 x=#pVB[i].texCoords.x y=#pVB[i].texCoords.y write myfile,"vt "+str$(x)+" "+str$(y) next i setprecision 0 'write out each face referring to position vertice and texture coordinates for i=0 to numIndices-1 step 3 x=1+#pIB[i] y=1+#pIB[i+1] z=1+#pIB[i+2] write myfile,"f "+" "+str$(x)+"/"+ltrim$(str$(x))+" "+str$(y)+"/"+ltrim$(str$(y))+" "+str$(z)+"/"+ltrim$(str$(z)) next i closefile myfile endif setprecision 3 endsub