April 29, 2024, 12:00:45 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


3D fish animation by Jolly Roger

Started by pistol350, September 04, 2007, 09:12:01 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

pistol350

My hat off to Jolly Roger!
Amazing! :o
How does he do it ?
Copy ,paste ,run and see it by yourself!  :-*

'Yes,it's essentially the same as the toothpaste/cone morph.
'Ten objects are generated from the two Jolly Modeller objects (fish with tail straight and fish with tail bent).
'They are all made children of the yaxispivot dummy object so they all move in a circle as it rotates.
'At any given time nine of them are out of view and one is visible.
'Frames zero to nine are shown in sequence then frames eight back to zero
'with the fish turned upside down so the tail move to the other side.




'Example of the use of the IBasic subroutines generated by Jolly Modeller
'to produce simple animation using morphing
'Jolly Roger June 2004
AUTODEFINE "OFF"
IF GETDXVERSION < 7
   MESSAGEBOX 0,"This program requires" + chr$(13) + "DirectX 7.0 or greater","Error"
   END
ENDIF

'Declare timer
DECLARE "kernel32",GetTickCount(),INT

DECLARE modeller_object(numberofsections:INT)
DEF numberoflayers,lcn[100],r[8],g[8],b[8],t[8],n:INT
DEF d[3000]:FLOAT

DEF win:WINDOW
DEF error,run:INT
DEF mult,angle:FLOAT
DEF scene,camera,light,lastframetime,timesincelastframe,yaxispivot,l:INT
DEF layer,colour,xcentre,zcentre,starty[100],xradius,zradius,numberofsections:INT
DEF xstart[1000],zstart[1000],startred[100],startgreen[100],startblue[100],starttrans[100]:FLOAT
DEF x[1000],z[1000],red[100],green[100],blue[100],trans[100],y[100],dy[100]:FLOAT
DEF dx[1000],dz[1000],dred[1000],dgreen[1000],dblue[1000],dtrans[1000]:FLOAT
DEF vertexnumber,numberofframes,frame,starttime,timetaken,eye1,eye2:INT
DEF startsideleft[100],startsideright[100],startfrontleft[100],startfrontright[100]:INT
DEF dsideleft[100],dsideright[100],dfrontleft[100],dfrontright[100]:FLOAT
numberofframes=10
DEF shape[numberofframes],direction:INT
direction=1
'Open a window
WINDOW win,0,0,640,480,@NOAUTODRAW,0,"Morph animation experiment",mainwindow

'Create a 3D screen for object preview
error=CREATE3DSCREEN(win,640,480)
IF error<>0
   'Couldn't open windowed Direct3D screen.Try opening fullscreen
   error=CREATE3DSCREEN(win,640,480,16)
   IF error<>0
    MESSAGEBOX win, "Could not create Direct3D screen","Error"
    CLOSEWINDOW win
    END
   ENDIF
ENDIF

D3DSETQUALITY win,@LIGHTON | @FILLSOLID | @SHADEGOURAUD
FRONTPEN win,RGB(255,255,255)
BACKPEN win,0
DRAWMODE win,@TRANSPARENT

'The parent scene frame
scene = D3DSCENE(win)
D3DCOMMAND scene,@SETSCENEBACKCOLOR,.2,.2,1

'Create and position the camera
camera = D3DCAMERA(scene)
D3DCOMMAND camera,@SETPOSITION,scene,0,400,-1200
D3DCOMMAND camera,@SETORIENTATION,scene,0,-SIN(20*6.28/360),COS(20*6.28/360),0,COS(20*6.28/360),SIN(20*6.28/360)

'Create and orient a light source
light = D3DLIGHT(scene,@LIGHTDIRECTIONAL,1.2,1.2,1.2)
D3DCOMMAND light,@SETORIENTATION,scene,-1,-1,1, -1,1,1

'Create dummy object for y axis pivot
yaxispivot=D3DSHAPE(scene,@SHAPECUSTOM)

'Read start object data
'Set all layer colour numbers to zero before read data
FOR l=0 TO 99:lcn[l]=0:NEXT l
readgoldfishbentdata
FOR layer=0 TO numberoflayers-1
  starty[layer]=d[layer*5]:startfrontleft[layer]=d[layer*5+1]:startfrontright[layer]=d[layer*5+2]
  startsideleft[layer]=d[layer*5+3]:startsideright[layer]=d[layer*5+4]
  colour=lcn[layer]
  startred[layer]=r[colour]:startgreen[layer]=g[colour]:startblue[layer]=b[colour]
  starttrans[layer]=t[colour]
NEXT layer
'Read target object data and fill the arrays which hold the
'data used to change the object each frame
'Set all layer colour numbers to zero before read data
FOR l=0 TO 99:lcn[l]=0:NEXT l
readgoldfishstraightdata
FOR layer=0 TO numberoflayers-1
  dy[layer]=(d[layer*5]-starty[layer])/(numberofframes-1)
  colour=lcn[layer]
  dred[layer]=(r[colour]-startred[layer])/(numberofframes-1)
  dgreen[layer]=(g[colour]-startgreen[layer])/(numberofframes-1)
  dblue[layer]=(b[colour]-startblue[layer])/(numberofframes-1)
  dtrans[layer]=(t[colour]-starttrans[layer])/(numberofframes-1)
  dfrontleft[layer]=(d[layer*5+1]-startfrontleft[layer])/(numberofframes-1)
  dfrontright[layer]=(d[layer*5+2]-startfrontright[layer])/(numberofframes-1)
  dsideleft[layer]=(d[layer*5+3]-startsideleft[layer])/(numberofframes-1)
  dsideright[layer]=(d[layer*5+4]-startsideright[layer])/(numberofframes-1)
NEXT layer
'Copy initial values to arrays used to generate object
FOR layer=0 TO numberoflayers-1
  d[layer*5]=starty[layer]:red[layer]=startred[layer]:green[layer]=startgreen[layer]
  blue[layer]=startblue[layer]:trans[layer]=starttrans[layer]
  d[layer*5+1]=startfrontleft[layer]:d[layer*5+2]=startfrontright[layer]
  d[layer*5+3]=startsideleft[layer]:d[layer*5+4]=startsideright[layer]
NEXT layer
'Generate one 3D object for each frame of the morph
FOR frame=0 TO numberofframes-1
  'Create object
  shape[frame]=modeller_object(16)
  D3DCOMMAND shape[frame],@ADDROTATION,0,0,1,1.571
  'Move all fish bar one out of view
  IF frame<>0
    'Move object out of view
    D3DCOMMAND shape[frame],@SETPOSITION,scene,0,0,10000
  ELSE
    D3DCOMMAND shape[frame],@SETPOSITION,yaxispivot,0,0,500
  ENDIF
  'Make all frame objects children of yaxispivot so they move
  'in a circle when it rotates
  D3DCOMMAND yaxispivot,@ADDCHILD,shape[frame]
  'Alter data in arrays to that for next frame
  FOR layer=0 TO numberoflayers-1
    d[layer*5]=d[layer*5]+dy[layer]:red[layer]=red[layer]+dred[layer]:green[layer]=green[layer]+dgreen[layer]
    blue[layer]=blue[layer]+dblue[layer]:trans[layer]=trans[layer]+dtrans[layer]
    d[layer*5+1]=d[layer*5+1]+dfrontleft[layer]
    d[layer*5+2]=d[layer*5+2]+dfrontright[layer]
    d[layer*5+3]=d[layer*5+3]+dsideleft[layer]
    d[layer*5+4]=d[layer*5+4]+dsideright[layer]
  NEXT layer
NEXT frame
'Create eyes
FOR l=0 TO 99:lcn[l]=0:NEXT l
readeyedata
'Convert colour data
FOR layer=0 TO numberoflayers-1
  colour=lcn[layer]
  red[layer]=r[colour]:green[layer]=g[colour]:blue[layer]=b[colour]
  trans[layer]=t[colour]
NEXT layer
eye1=modeller_object(8)
D3DCOMMAND eye1,@SETPOSITION,shape[0],10,50,50
D3DCOMMAND eye1,@SCALE,.2,.2,.2
D3DCOMMAND eye1,@ADDROTATION,1,0,0,1.571
D3DCOMMAND yaxispivot,@ADDCHILD,eye1
eye2=modeller_object(8)
D3DCOMMAND eye2,@SETPOSITION,shape[0],10,50,-50
D3DCOMMAND eye2,@ADDROTATION,1,0,0,-1.571
D3DCOMMAND eye2,@SCALE,.2,.2,.2
D3DCOMMAND yaxispivot,@ADDCHILD,eye2

frame=0
STARTTIMER win,40
starttime=GetTickCount()
lastframetime=GetTickCount()-1
run=1
'Process messages until somebody closes us
WAITUNTIL run=0

'Delete all the frames
D3DDELETE light
D3DDELETE camera
FOR frame=0 TO numberofframes-1
  D3DDELETE shape[frame]
NEXT frame
D3DDELETE eye1
D3DDELETE eye2
D3DDELETE yaxispivot
D3DDELETE scene
DELETEFILE(GETSTARTPATH+"temporary.x")
'Hide cursor.Avoids possible cursor distortion
SETCURSOR win,@CSCUSTOM,0
CLOSEWINDOW win
END


SUB mainwindow
  SELECT @class
   CASE @IDCHAR
      if (@CODE = ASC("Q")) | (@CODE = ASC("q")) THEN run = 0
   CASE @IDCREATE
      centerwindow win
   CASE @IDCLOSEWINDOW
      run=0
    CASE @IDTIMER
      'Move current frame out of view
      D3DCOMMAND shape[frame],@SETPOSITION,yaxispivot,0,0,10000
      frame=frame+direction
      'Move shape for new frame into view
      D3DCOMMAND shape[frame],@SETPOSITION,yaxispivot,0,0,500
      IF direction=-1
        'Turn fish body upside down so only need 10 objects for a 20 frame animation :)
        D3DCOMMAND shape[frame],@ADDROTATION,0,1,0,3.142
      ENDIF
      'Reverse the animation if reaches beginning or end
      IF frame=numberofframes-1 | frame=0
          direction=-direction
      ENDIF
   CASE @IDDXUPDATE
      'Find time since last frame to make things run at a constant speed
      timesincelastframe=GetTickCount()-lastframetime
      IF timesincelastframe>2
        lastframetime=GetTickCount()
        mult=timesincelastframe/8
        'Rotate yaxispivot to move fish in circle
       D3DCOMMAND yaxispivot,@ADDROTATION,0,1,0,(-.2 * (3.1415/180))*mult
      'Render the scene to the DirectX surface
      D3DRENDER scene,camera
      'Add any 2D elements after the scene is rendered.
      MOVE win,10,10:PRINT win,"Press Q to exit"
      'Show the DirectX surface   
      DXFLIP win,0,0
      ENDIF
  ENDSELECT
RETURN


SUB modeller_object(numberofsections)
'Number of sections must be 3 or above
'Top face present and bottom face present should be 1 or 0
DEF objecthandle1:INT
IF numberofsections>2
  DEF objecthandle,colour:INT
  DEF facedata[100],section,vertex[10000],facenumber,xcentre,zcentre,xradius,zradius:INT
  DEF angle:FLOAT
  DEF layer,vertexnumber,normal:INT
  objecthandle=D3DSHAPE(scene,@SHAPECUSTOM)
  normal=D3DCOMMAND (objecthandle,@ADDNORMAL,0,-1,0)
  'Create vertices
  FOR layer=0 TO numberoflayers-1
   xcentre=-160+(d[layer*5+1]+d[layer*5+2])/2
   zcentre=-160+(d[layer*5+4]+d[layer*5+3])/2
   xradius=(d[layer*5+2]-d[layer*5+1])/2
   zradius=(d[layer*5+4]-d[layer*5+3])/2 
   FOR section=0 TO numberofsections-1
     angle=6.283*section/numberofsections
     vertexnumber=layer*numberofsections+section
     vertex[vertexnumber]=D3DCOMMAND (objecthandle,@ADDVERTEX,xcentre+xradius*SIN(angle),d[layer*5],zcentre+zradius*COS(angle))
    NEXT section
  NEXT layer
  'Create side faces
  facedata[0]=4:facedata[9]=0
  facedata[2]=normal:facedata[4]=normal:facedata[6]=normal:facedata[8]=normal
  FOR layer=1 TO numberoflayers-1
   FOR section=0 TO numberofsections-1
     facedata[7]=vertex[(layer-1)*numberofsections+section]
     facedata[5]=vertex[layer*numberofsections+section]
     IF section<>numberofsections-1
       facedata[3]=vertex[layer*numberofsections+section+1]
       facedata[1]=vertex[(layer-1)*numberofsections+section+1]
     ELSE
       facedata[3]=vertex[layer*numberofsections]
       facedata[1]=vertex[(layer-1)*numberofsections]
     ENDIF
     D3DCOMMAND objecthandle,@ADDFACES,facedata
      'Colour face
      colour=lcn[layer-1]
      D3DCOMMAND objecthandle,@SETFACECOLOR,facenumber,r[colour]/255,g[colour]/255,b[colour]/255,1-t[colour]/255
      facenumber=facenumber+1
   NEXT section
   D3DCOMMAND objecthandle,@CUSTOMINIT
  NEXT layer
  'Create top face
  facedata[0]=numberofsections:facedata[2*numberofsections+1]=0
  FOR section=0 TO numberofsections-1
    facedata[2*section+1]=vertex[(numberoflayers-1)*numberofsections+section]
    facedata[2*section+2]=normal
  NEXT section
  D3DCOMMAND objecthandle,@ADDFACES,facedata
  'Colour face
  colour=lcn[numberoflayers-1]
  D3DCOMMAND objecthandle,@SETFACECOLOR,facenumber,r[colour]/255,g[colour]/255,b[colour]/255,1-t[colour]/255
  facenumber=facenumber+1
  D3DCOMMAND objecthandle,@CUSTOMINIT
  'Create bottom face
  facedata[0]=numberofsections:facedata[2*numberofsections+1]=0
  FOR section=numberofsections-1 TO 0 STEP -1
    facedata[2*(numberofsections-1-section)+1]=vertex[section]
    facedata[2*(numberofsections-1-section)+2]=normal
  NEXT section
  D3DCOMMAND objecthandle,@ADDFACES,facedata
  'Colour face
  colour=lcn[0]
  D3DCOMMAND objecthandle,@SETFACECOLOR,facenumber,r[colour]/255,g[colour]/255,b[colour]/255,1-t[colour]/255
  facenumber=facenumber+1
  D3DCOMMAND objecthandle,@CUSTOMINIT
  'Save object without normals,delete it then reload it
  'Quick and dirty way to get DirectX to calculate normals
  D3DCOMMAND objecthandle,@SAVESHAPE,GETSTARTPATH+"temporary.x",@FORMATTEXT,@SAVEMATERIALS
  D3DDELETE objecthandle
  objecthandle1=D3DSHAPE(scene,@SHAPECUSTOM)
  D3DCOMMAND objecthandle1,@LOADSHAPE,GETSTARTPATH+"temporary.x",0
ENDIF
RETURN objecthandle1


SUB readgoldfishstraightdata
numberoflayers=10
d=-160,118,202,157,163,-102,148,172,153,167,-82,148,172,150,170,-62,135,185,144,176
d[20]=-42,129,191,140,180,2,124,196,136,184,49,124,196,137,183,69,131,189,141,179
d[40]=89,144,174,149,171,98,156,164,157,163
r=255:g=205:b=0:t=0
RETURN


SUB readgoldfishbentdata
numberoflayers=10
d=-150,118,202,119,125,-103,148,172,134,148,-82,148,172,137,157,-62,135,185,136,168
d[20]=-42,129,191,135,175,2,124,196,136,184,49,124,196,137,183,69,131,189,141,179
d[40]=89,144,174,149,171,98,156,164,157,163
r=255,-1:g=205:b=0:t=0
RETURN


SUB readeyedata
numberoflayers=4
d=-160,100,220,100,220,-140,117,203,117,203,-127,144,176,144,176,-123,157,163,157,163
lcn=0,0,1,1
r=255,0,0,0,255,255,0,150
g=255,0,255,0,255,0,255,100
b=255,0,0,255,0,255,255,0
t=0,0,0,0,0,0,0,0
RETURN
Regards,

Peter B.

GWS

I like that one ..  :)

This 3D stuff will be very interesting to try out ..

Graham
Tomorrow may be too late ..