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
That's really weird .. :)
Very clever.
Graham