April 29, 2024, 01:26:57 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


3D 'Wonky clock by Jolly Roger

Started by pistol350, September 04, 2007, 09:29:46 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

pistol350

Custom 3D clock!!
Amazing!!!!!!!!!!! :o
have a look!!

'Wonky clock
'Shows usage of data subroutines created by Line extruder programme
'Jolly Roger Oct 2004
'Requires IBasic 1.97 or greater.

IF GETDXVERSION < 7
   MESSAGEBOX 0,"This program requires" + chr$(13) + "DirectX 7.0 or greater","Error"
   END
ENDIF

DECLARE "kernel32",GetTickCount(),INT
DEF win:WINDOW
DEF error,run:INT
DEF mult:FLOAT
DEF scene,camera,light,lastframetime,timesincelastframe,shape,secondhand,minutehand,hourhand:INT
DEF secondhandpivot,minutehandpivot,hourhandpivot,clockpivot:INT
DEF lineclosed[50],numberofpointsinline[50],pointx[10000],pointy[10000],numberoflines:INT
DEF timestring:STRING
DEF hours,minutes:FLOAT
DEF seconds,extrusionheight,linewidth:INT

clockcentrex=-15:clockcentrey=70:clockcentrez=-20

'Open a window
WINDOW win,0,0,640,480,@NOAUTODRAW,0,"Wonky clock",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

DECLARE extrusionobject(objectparent:INT)

DECLARE lineangle(x1:INT,y1:INT,x2:INT,y2:INT)

'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,0,-1000
D3DCOMMAND camera,@SETORIENTATION,scene,0,0,1,0,1,0

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

clockpivot=D3DSHAPE(scene,@SHAPECUSTOM)
D3DCOMMAND clockpivot,@SETROTATION,scene,0,1,0,.005

GOSUB readclockfacedata

shape=extrusionobject(clockpivot)
D3DCOMMAND shape,@SETPOSITION,clockpivot,20,-110,10

secondhandpivot=D3DSHAPE(clockpivot,@SHAPECUSTOM)

secondhand=D3DSHAPE(secondhandpivot,@SHAPECUBE,5,200,5)
D3DCOMMAND(secondhand,@SETPOSITION,secondhandpivot,0,100,0)

minutehandpivot=D3DSHAPE(clockpivot,@SHAPECUSTOM)

GOSUB readminutehanddata
minutehand=extrusionobject(minutehandpivot)
D3DCOMMAND minutehand,@SCALE,.22,.22,.22
D3DCOMMAND(minutehand,@SETPOSITION,minutehandpivot,5,65,0)

hourhandpivot=D3DSHAPE(clockpivot,@SHAPECUSTOM)

GOSUB readhourhanddata
hourhand==extrusionobject(hourhandpivot)
D3DCOMMAND hourhand,@SCALE,.2,.2,.2
D3DCOMMAND(hourhand,@SETPOSITION,hourhandpivot,0,55,0)

lastframetime=GetTickCount()-1
run=1

'Process messages until somebody closes us
WAITUNTIL run=0

'Delete all the frames
D3DDELETE light
D3DDELETE camera
D3DDELETE clockpivot
D3DDELETE shape
D3DDELETE secondhand
D3DDELETE secondhandpivot
D3DDELETE minutehand
D3DDELETE minutehandpivot
D3DDELETE hourhand
D3DDELETE hourhandpivot
D3DDELETE scene
'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 @IDDXUPDATE
      'Find time since last frame to make things run at a constant speed
      timesincelastframe=GetTickCount()-lastframetime
      IF timesincelastframe>2
        timestring$=TIME$
        seconds=VAL(RIGHT$(timestring$,2))
        minutes=VAL(MID$(timestring$,4,2))+seconds/60
        hours=VAL(LEFT$(timestring$,2))+minutes/60
        hours=hours%12+minutes/60
        D3DCOMMAND (secondhandpivot,@SETORIENTATION,clockpivot,0,0,1,SIN(seconds*6.283/60),COS(seconds*6.283/60),0)
        D3DCOMMAND (minutehandpivot,@SETORIENTATION,clockpivot,0,0,1,SIN(minutes*6.283/60),COS(minutes*6.283/60),0)
        D3DCOMMAND (hourhandpivot,@SETORIENTATION,clockpivot,0,0,1,SIN(hours*6.283/12),COS(hours*6.283/12),0)
        lastframetime=GetTickCount()
        mult=timesincelastframe/8
      'Move the frames according to their current rotation, direction and velocity
      D3DMOVE win,mult
      'Render the scene to the DirectX surface
      D3DRENDER scene,camera
      'Add any 2D elements after the scene is rendered.
      MOVE win,5,5
      PRINT win,"Press Q to exit"
      'Show the DirectX surface   
      DXFLIP win,0,0
      ENDIF
  ENDSELECT
RETURN



SUB extrusionobject(objectparent)
  DEF objecthandle,pointsinline,vertex0[1000],vertex1[1000],vertex2[1000],vertex3[1000],verticescreated:INT
  DEF faceinfo[9],topfacenormal,bottomfacenormal,actualhalfwidth:INT
  DEF endfacenormal1,endfacenormal2,normal1,normal2,pointsused:INT
  DEF linesegmentangle[1000],pointangle[1000],linesegmentangledifference[1000]:FLOAT
  DEF halfextrusionheight:FLOAT
  halfextrusionheight=extrusionheight/2.0
  pointsused=0
  objecthandle=D3DSHAPE(objectparent,@SHAPECUSTOM)
  FOR linenumber=0 TO numberoflines-1
    'Work out line angles
    pointsinline=numberofpointsinline[linenumber]
    linesegmentangledifference[0]=0:linesegmentangledifference[pointsinline-1]=0
    FOR point=0 TO pointsinline-2
      linesegmentangle[point]=lineangle(pointx[pointsused+point],pointy[pointsused+point],pointx[pointsused+point+1],pointy[pointsused+point+1])
    NEXT point
    IF lineclosed[linenumber]
      linesegmentangle[pointsinline-1]=lineangle(pointx[pointsused+pointsinline-1],pointy[pointsused+pointsinline-1],pointx[pointsused],pointy[pointsused])
    ENDIF
    'Work out angles at points
    IF lineclosed[linenumber]=0
      pointangle[0]=linesegmentangle[0]
    ELSE
      linesegmentangledifference[0]=linesegmentangle[0]-linesegmentangle[pointsinline-1]
      IF ABS(linesegmentangledifference[0])>3.142
         linesegmentangledifference[0]=linesegmentangledifference[0]-6.283*SGN(linesegmentangledifference[0])
      ENDIF
      pointangle[0]=linesegmentangle[pointsinline-1]+linesegmentangledifference[0]/2
    ENDIF
    IF pointsinline>2
      FOR point=1 TO pointsinline-2
        linesegmentangledifference[point]=linesegmentangle[point]-linesegmentangle[point-1]
        IF ABS(linesegmentangledifference[point])>3.142
           linesegmentangledifference[point]=linesegmentangledifference[point]-6.283*SGN(linesegmentangledifference[point])
        ENDIF
        pointangle[point]=linesegmentangle[point-1]+linesegmentangledifference[point]/2
      NEXT point
    ENDIF
    IF lineclosed[linenumber]=0
       pointangle[pointsinline-1]=linesegmentangle[pointsinline-2]
    ELSE
      linesegmentangledifference[pointsinline-1]=linesegmentangle[pointsinline-1]-linesegmentangle[pointsinline-2]
      IF ABS(linesegmentangledifference[pointsinline-1])>3.142
         linesegmentangledifference[pointsinline-1]=linesegmentangledifference[pointsinline-1]-6.283*SGN(linesegmentangledifference[pointsinline-1])
      ENDIF
      pointangle[pointsinline-1]=linesegmentangle[pointsinline-2]+linesegmentangledifference[pointsinline-1]/2
    ENDIF
    'Create vertices.Four per point in line
    FOR point=0 TO pointsinline-1
      IF (point=0 | point=pointsinline-1) & lineclosed[linenumber]=0
        actualhalfwidth=.5*linewidth
      ELSE
        IF ABS(linesegmentangledifference[point])<2.1
          actualhalfwidth=.5*linewidth/COS(ABS(linesegmentangledifference[point]/2))
        ELSE
          actualhalfwidth=linewidth
        ENDIF
      ENDIF
      vertex0[point]=D3DCOMMAND (objecthandle,@ADDVERTEX,pointx[pointsused+point]-actualhalfwidth*cos(pointangle[point]),pointy[pointsused+point]+actualhalfwidth*SIN(pointangle[point]),halfextrusionheight)
      vertex1[point]=D3DCOMMAND (objecthandle,@ADDVERTEX,pointx[pointsused+point]+actualhalfwidth*cos(pointangle[point]),pointy[pointsused+point]-actualhalfwidth*SIN(pointangle[point]),halfextrusionheight)
      vertex2[point]=D3DCOMMAND (objecthandle,@ADDVERTEX,pointx[pointsused+point]+actualhalfwidth*COS(pointangle[point]),pointy[pointsused+point]-actualhalfwidth*SIN(pointangle[point]),-1*halfextrusionheight)
      vertex3[point]=D3DCOMMAND (objecthandle,@ADDVERTEX,pointx[pointsused+point]-actualhalfwidth*COS(pointangle[point]),pointy[pointsused+point]+actualhalfwidth*SIN(pointangle[point]),-1*halfextrusionheight)
    NEXT point
    'Create top faces
    topfacenormal=D3DCOMMAND(objecthandle,@ADDNORMAL,0,0,1)
    FOR point=0 TO pointsinline-2
      faceinfo=4,vertex0[point],topfacenormal,vertex1[point],topfacenormal,vertex1[point+1],topfacenormal,vertex0[point+1],topfacenormal
      D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
    NEXT point
    'Create bottom faces
    bottomfacenormal=D3DCOMMAND(objecthandle,@ADDNORMAL,0,0,-1)
    FOR point=0 TO pointsinline-2
      faceinfo=4,vertex2[point],bottomfacenormal,vertex3[point],bottomfacenormal,vertex3[point+1],bottomfacenormal,vertex2[point+1],bottomfacenormal
      D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
    NEXT point
    'Create side faces
    FOR point=0 TO pointsinline-2
       IF linesegmentangledifference[point]>1.571/2
         normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(linesegmentangle[point]),-SIN(linesegmentangle[point]),0)
       ELSE
         normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(pointangle[point]),-SIN(pointangle[point]),0)
       ENDIF
       IF linesegmentangledifference[point+1]>1.571/2
         normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(linesegmentangle[point]),-SIN(linesegmentangle[point]),0)
       ELSE
         normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(pointangle[point+1]),-SIN(pointangle[point+1]),0)
       ENDIF
       faceinfo=4,vertex3[point],normal1,vertex0[point],normal1,vertex0[point+1],normal2,vertex3[point+1],normal2
       D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)

       IF linesegmentangledifference[point]>1.571/2
         normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(linesegmentangle[point]),SIN(linesegmentangle[point]),0)
       ELSE
         normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(pointangle[point]),SIN(pointangle[point]),0)
       ENDIF
       IF linesegmentangledifference[point+1]>1.571/2
         normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(linesegmentangle[point]),SIN(linesegmentangle[point]),0)
       ELSE
         normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(pointangle[point+1]),SIN(pointangle[point+1]),0)
       ENDIF
       faceinfo=4,vertex1[point],normal1,vertex2[point],normal1,vertex2[point+1],normal2,vertex1[point+1],normal2
       D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
    NEXT point
    'Add end faces/close object
    IF lineclosed[linenumber]
        'Close object
        'Top face
        faceinfo=4,vertex1[0],topfacenormal,vertex0[0],topfacenormal,vertex0[pointsinline-1],topfacenormal,vertex1[pointsinline-1],topfacenormal
        D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
        'Bottom face
        faceinfo=4,vertex3[0],bottomfacenormal,vertex2[0],bottomfacenormal,vertex2[pointsinline-1],bottomfacenormal,vertex3[pointsinline-1],bottomfacenormal
        D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
        'Side faces
        IF linesegmentangledifference[0]>1.571/2
          normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(linesegmentangle[pointsinline-2]),-SIN(linesegmentangle[pointsinline-2]),0)
        ELSE
          normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(pointangle[0]),-SIN(pointangle[0]),0)
        ENDIF
        IF linesegmentangledifference[pointsinline-1]>1.571/2
          normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(linesegmentangle[pointsinline-2]),-SIN(linesegmentangle[pointsinline-2]),0)
        ELSE
          normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,-COS(pointangle[pointsinline-1]),-SIN(pointangle[pointsinline-1]),0)
        ENDIF
        faceinfo=4,vertex0[0],normal1,vertex3[0],normal1,vertex3[pointsinline-1],normal2,vertex0[pointsinline-1],normal2
        D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)

        IF linesegmentangledifference[0]>1.571/2
          normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(linesegmentangle[pointsinline-2]),SIN(linesegmentangle[pointsinline-2]),0)
        ELSE
          normal1=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(pointangle[0]),SIN(pointangle[0]),0)
        ENDIF
        IF linesegmentangledifference[pointsinline-1]>1.571/2
          normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(linesegmentangle[pointsinline-2]),SIN(linesegmentangle[pointsinline-2]),0)
        ELSE
          normal2=D3DCOMMAND (objecthandle,@ADDNORMAL,COS(pointangle[pointsinline-1]),SIN(pointangle[pointsinline-1]),0)
        ENDIF
        faceinfo=4,vertex2[0],normal1,vertex1[0],normal1,vertex1[pointsinline-1],normal2,vertex2[pointsinline-1],normal2
        D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
    ELSE
       'Add endfaces
        endfacenormal1=D3DCOMMAND (objecthandle,@ADDNORMAL,-SIN(linesegmentangle[0]),-COS(linesegmentangle[0]),0)
        faceinfo=4,vertex3[0],endfacenormal1,vertex2[0],endfacenormal1,vertex1[0],endfacenormal1,vertex0[0],endfacenormal1
        D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
        endfacenormal2=D3DCOMMAND (objecthandle,@ADDNORMAL,SIN(linesegmentangle[pointsinline-2]),COS(linesegmentangle[pointsinline-2]),0)
        faceinfo=4,vertex0[pointsinline-1],endfacenormal2,vertex1[pointsinline-1],endfacenormal2,vertex2[pointsinline-1],endfacenormal2,vertex3[pointsinline-1],endfacenormal2
        D3DCOMMAND(objecthandle,@ADDFACES,faceinfo)
    ENDIF
    pointsused=pointsused+pointsinline
  NEXT linenumber
  D3DCOMMAND objecthandle,@CUSTOMINIT
RETURN objecthandle



SUB lineangle(x1,y1,x2,y2)
  DEF angle:FLOAT
  DEF dx,dy:INT
  dx=x2-x1:dy=y2-y1
  IF dy=0
    IF dx<0
       angle=3.124+1.571
    ELSE
       angle=1.571
    ENDIF
  ELSE
     angle=ATAN(dx/dy)
     IF dy<0 THEN angle=3.142+angle
     IF angle<0 THEN angle=6.283+angle
  ENDIF
RETURN angle



SUB readclockfacedata
linewidth=10
extrusionheight=10
numberoflines=17
lineclosed=1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0
numberofpointsinline=80,2,6,2,6,7,3,2,8,10,3,11,8,2,7,2,2
pointx=-44,-22,3,26,48,76,97,114,131,142,153,166,179,191,204,209,217
pointx[17]=224,230,235,235,235,235,235,235,232,224,217,204,194,181
pointx[31]=168,153,140,125,110,89,63,48,28,3,-22,-44,-71,-93,-114,-134
pointx[47]=-155,-177,-198,-213,-226,-239,-247,-254,-256,-262,-264,-267
pointx[59]=-269,-269,-269,-269,-269,-267,-260,-252,-241,-232,-219,-205
pointx[71]=-196,-183,-170,-157,-144,-132,-114,-91,-65,-52,-52,-35,-9
pointx[84]=-7,-22,-33,-5,82,82,132,153,161,153,140,162,176,194,204
pointx[99]=189,198,194,176,142,140,176,155,159,89,50,50,69,89,95,82
pointx[115]=59,-29,-43,-61,-63,-50,-29,-22,-28,-44,-65,-185,-144,-170
pointx[129]=-205,-219,-217,-192,-177,-181,-200,-211,-205,-191,-191
pointx[140]=-200,-224,-232,-220,-200,-192,-196,-204,-198,-198,-170
pointx[151]=-142,-132,-134,-149,-170,-177,-134,-134,-114,-114
pointy=353,353,353,348,346,338,333,325,318,305,290,275,262,249,234
pointy[15]=213,196,176,155,134,108,86,58,29,5,-14,-33,-48,-61,-78,-91
pointy[31]=-104,-117,-127,-140,-147,-155,-162,-170,-176,-176,-176,-176
pointy[43]=-176,-176,-174,-168,-162,-161,-153,-146,-132,-117,-102,-82
pointy[55]=-59,-35,-14,14,35,63,88,114,140,162,181,198,211,226,239
pointy[70]=254,267,280,295,305,318,329,333,337,337,323,282,323,323
pointy[84]=303,295,282,284,305,264,254,254,234,219,205,205,147,142
pointy[98]=127,119,106,86,84,7,-28,-26,-5,-46,-63,-67,-91,-89,-91,-112
pointy[114]=-123,-125,-63,-76,-106,-127,-140,-142,-127,-110,-104,-99
pointy[126]=-46,-54,-104,50,35,24,13,0,-20,-26,-11,9,24,43,119,119
pointy[142]=136,153,155,140,116,78,232,185,228,228,213,192,183,189
pointy[156]=205,295,262,303,264
RETURN



SUB readhourhanddata
linewidth=20
extrusionheight=10
numberoflines=1
lineclosed=1
numberofpointsinline=22
pointx=0,20,63,84,91,93,82,61,39,39,29,3,-20,-31,-31,-63,-84,-101,-95
pointx[19]=-80,-58,-29
pointy=486,425,395,374,350,322,299,279,262,-277,-305,-316,-307,-277
pointy[14]=260,275,299,333,367,393,411,419
RETURN


SUB readminutehanddata
linewidth=20
extrusionheight=10
numberoflines=1
lineclosed=1
numberofpointsinline=8
pointx=-24,3,3,-3,-24,-46,-54,-54
pointy=490,425,-282,-305,-316,-308,-286,423
RETURN
Regards,

Peter B.

GWS

That's really weird ..  :)

Very clever.

Graham
Tomorrow may be too late ..