|
 |
|
DBPro Text Graphic Games:
DBPro Articles:
[Offsite] DarkBasic Professional & Dark GDK/C++:
|
|
|
rem ################################################################### rem Load Object - By: Todd Riggins - ExoDev.Com - Dec. 8, 2010 rem 3D Object Format Info: http://en.wikipedia.org/wiki/Obj rem ###################################################################
rem ################################################################### rem GLOBALS rem ###################################################################
GLOBAL global_CamID as INTEGER
DIM array_string(0) AS STRING
TYPE TYPE_VERTEX x AS FLOAT y AS FLOAT z AS FLOAT ENDTYPE DIM array_vertex(0) AS TYPE_VERTEX
TYPE TYPE_TEXCOORD u AS FLOAT v AS FLOAT ENDTYPE DIM array_texcoord(0) AS TYPE_TEXCOORD
TYPE TYPE_NORMAL x AS FLOAT y AS FLOAT z AS FLOAT ENDTYPE DIM array_normal(0) AS TYPE_NORMAL
TYPE TYPE_FACE V1Vertex AS INTEGER V1TexCoord AS INTEGER V1Normal AS INTEGER V2Vertex AS INTEGER V2TexCoord AS INTEGER V2Normal AS INTEGER V3Vertex AS INTEGER V3TexCoord AS INTEGER V3Normal AS INTEGER ENDTYPE DIM array_face(0) AS TYPE_FACE
GLOBAL gThisStringPosition AS INTEGER GLOBAL gIndiceStep AS INTEGER GLOBAL gNumberOfVertices,gNumberOfFaces AS INTEGER
GLOBAL Global_CamID AS INTEGER GLOBAL Global_RightMouseClick AS INTEGER
rem ################################################################### rem Start Main Loop rem ###################################################################
Main() END
rem ################################################################### rem Main Loop rem ###################################################################
FUNCTION Main() LOCAL local_ObjectID AS INTEGER LOCAL local_SpaceHelm2Image AS INTEGER rem Initialize Display Setup InitDisplaySetup() rem Retrieve image used by obj 3d object local_SpaceHelm2Image = GetNewImageID() LOAD IMAGE "BadGuy1.png",local_SpaceHelm2Image,0 rem Load the obj 3d file local_ObjectID = GetNewObjectID() LoadObj("BadGuy1.obj",local_ObjectID,local_SpaceHelm2Image)
rem Don't know if Sculptris can save out normals in it's obj export rem so I manually create smoothing normals for it here SET OBJECT NORMALS local_ObjectID SET OBJECT SMOOTHING local_ObjectID,100 rem Rotate the object to face the camera ROTATE OBJECT local_ObjectID,0,180,0
rem Main loop REPEAT UserControls()
TEXT 10,30,"Faces:"+str$(gNumberOfFaces) TEXT 1,1,"FPS:"+STR$(SCREEN FPS()) SYNC UNTIL ESCAPEKEY()=1 ENDFUNCTION
rem ################################################################### rem FUNCTIONS rem ###################################################################
rem Setup Display and Camera FUNCTION InitDisplaySetup() SYNC ON SYNC RATE 30
SET WINDOW POSITION 0,0 SET WINDOW LAYOUT 0,0,0 MAXIMIZE WINDOW
SET DISPLAY MODE DESKTOP WIDTH(),DESKTOP HEIGHT(),0, 0 SET WINDOW OFF
rem create camera global_CamID = 1 MAKE CAMERA global_CamID POSITION CAMERA global_CamID,0,2,-1000 COLOR BACKDROP global_CamID, RGB(16,16,16) SET CAMERA FOV global_CamID,45 SET CAMERA RANGE global_CamID,1,10000 HIDE LIGHT 0
rem create light to follow camera MAKE LIGHT 1 SET LIGHT RANGE 1,7000 POSITION LIGHT 1,CAMERA POSITION X(global_CamID),CAMERA POSITION Y(global_CamID),CAMERA POSITION Z(global_CamID) DISABLE ESCAPEKEY ENDFUNCTION
Function UserControls() LOCAL local_CameraAngleX as FLOAT LOCAL local_CameraAngleY as FLOAT LOCAL local_mmovex as INTEGER LOCAL local_mmovex as INTEGER local_mmovex = mousemovex() local_mmovey = mousemovey()
` Camera Control: ` Move Camera Position `W=17 if (keystate(17)=1) Move Camera global_CamID,10.0 endif `S=31 if (keystate(31)=1) Move Camera global_CamID,-10.0 endif `A=30 if (keystate(30)=1) ` endif `D=32 if (keystate(32)=1) ` endif
` Rotate camera on right click if mouseclick()=2 if Global_RightMouseClick = 0 Global_RightMouseClick = 1 hide mouse endif ` keep mouse centered when rotating camera position mouse screen width()/2, screen height()/2 ` Get Current Anlges local_CameraAngleX = Camera Angle X(global_CamID) local_CameraAngleY = Camera Angle Y(global_CamID) ` create a rotation axis based on controller movement local_CameraAngleX = WrapValue ( local_CameraAngleX + (local_mmovey) ) local_CameraAngleY = WrapValue ( local_CameraAngleY + (local_mmovex) ) ` rotate camera and lock x-axis between 0 and 90 if ((( local_CameraAngleX >= 0 ) and ( local_CameraAngleX <= 90 )) or (( local_CameraAngleX >= 270 ) and ( local_CameraAngleX < 360 ))) XRotate Camera global_CamID, local_CameraAngleX endif YRotate Camera global_CamID, local_CameraAngleY else if mouseclick()=0 and Global_RightMouseClick = 1 Global_RightMouseClick = 0 position mouse screen width()/2, screen height()/2 show mouse endif endif rem keep light at current camera position POSITION LIGHT 1,CAMERA POSITION X(global_CamID),CAMERA POSITION Y(global_CamID),CAMERA POSITION Z(global_CamID) EndFunction
rem Load in a .obj 3d file FUNCTION LoadObj(Filename$,ObjectID,ImageID) LOCAL local_index,local_index2 AS INTEGER LOCAL local_count AS INTEGER LOCAL vertex_index AS INTEGER LOCAL indice_index AS INTEGER LOCAL local_vi AS INTEGER LOCAL local_tci AS INTEGER LOCAL local_ni AS INTEGER LOCAL local_vx AS FLOAT LOCAL local_vy AS FLOAT LOCAL local_vz AS FLOAT LOCAL local_u AS FLOAT LOCAL local_v AS FLOAT LOCAL local_nx AS FLOAT LOCAL local_ny AS FLOAT LOCAL local_nz AS FLOAT
rem store file in memory/array of strings OPEN TO READ 1,Filename$ IF FILE OPEN(1)=1 REPEAT READ STRING 1,thisLine$ IF thisLine$<>"" ADD TO STACK array_string(0) local_index = ARRAY COUNT(array_string(0)) array_string(local_index)=thisLine$ ENDIF UNTIL FILE END(1)=1 ENDIF CLOSE FILE 1 local_count = ARRAY COUNT(array_string(0)) FOR local_index=1 TO local_count IF UPPER$(LEFT$(array_string(local_index),2))="V " ADD TO STACK array_vertex(0) local_index2 = ARRAY COUNT(array_vertex(0)) array_vertex(local_index2).x=GetFloatFromString(array_string(local_index),2) array_vertex(local_index2).y=GetFloatFromString(array_string(local_index),gThisStringPosition) array_vertex(local_index2).z=GetFloatFromString(array_string(local_index),gThisStringPosition) ENDIF IF UPPER$(LEFT$(array_string(local_index),3))="VT " ADD TO STACK array_texcoord(0) local_index2 = ARRAY COUNT(array_texcoord(0)) array_texcoord(local_index2).u=GetFloatFromString(array_string(local_index),3) array_texcoord(local_index2).v=GetFloatFromString(array_string(local_index),gThisStringPosition) ENDIF IF UPPER$(LEFT$(array_string(local_index),3))="VN " ADD TO STACK array_normal(0) local_index2 = ARRAY COUNT(array_normal(0)) array_normal(local_index2).x=GetFloatFromString(array_string(local_index),3) array_normal(local_index2).y=GetFloatFromString(array_string(local_index),gThisStringPosition) array_normal(local_index2).z=GetFloatFromString(array_string(local_index),gThisStringPosition) ENDIF IF UPPER$(LEFT$(array_string(local_index),2))="F " ADD TO STACK array_face(0) local_index2 = ARRAY COUNT(array_face(0)) gIndiceStep=1 : array_face(local_index2).V1Vertex=GetIntegerFromString(array_string(local_index),2) gIndiceStep=2 : array_face(local_index2).V1TexCoord=GetIntegerFromString(array_string(local_index),gThisStringPosition) gIndiceStep=3 : array_face(local_index2).V1Normal=GetIntegerFromString(array_string(local_index),gThisStringPosition) gIndiceStep=1 : array_face(local_index2).V2Vertex=GetIntegerFromString(array_string(local_index),gThisStringPosition) gIndiceStep=2 : array_face(local_index2).V2TexCoord=GetIntegerFromString(array_string(local_index),gThisStringPosition) gIndiceStep=3 : array_face(local_index2).V2Normal=GetIntegerFromString(array_string(local_index),gThisStringPosition)
gIndiceStep=1 : array_face(local_index2).V3Vertex=GetIntegerFromString(array_string(local_index),gThisStringPosition) gIndiceStep=2 : array_face(local_index2).V3TexCoord=GetIntegerFromString(array_string(local_index),gThisStringPosition) gIndiceStep=3 : array_face(local_index2).V3Normal=GetIntegerFromString(array_string(local_index),gThisStringPosition) ENDIF NEXT gNumberOfVertices=ARRAY COUNT(array_vertex(0)) gNumberOfFaces=ARRAY COUNT(array_face(0))
rem Build Obj Mesh MAKE OBJECT TRIANGLE ObjectID,0,0,0,1,1,0,2,0,0 ` here: triangle coordinates don't matter MAKE MESH FROM OBJECT 1, ObjectID FOR local_index=1 TO gNumberOfFaces-1 ADD LIMB ObjectID,local_index,1 NEXT DELETE MESH 1 MAKE MESH FROM OBJECT 1, ObjectID DELETE OBJECT ObjectID MAKE OBJECT ObjectID,1,ImageID DELETE MESH 1
indice_index=0 vertex_index=0 LOCK VERTEXDATA FOR LIMB ObjectID, 0 FOR local_index=1 TO gNumberOfFaces
local_vi=array_face(local_index).V1Vertex local_vx=array_vertex(local_vi).x local_vy=array_vertex(local_vi).y local_vz=array_vertex(local_vi).z SET VERTEXDATA POSITION vertex_index,local_vx,local_vy,local_vz local_tci=array_face(local_index).V1TexCoord IF local_tci>0 local_u = array_texcoord(local_tci).u local_v = array_texcoord(local_tci).v SET VERTEXDATA UV vertex_index,0,local_u,-local_v ELSE SET VERTEXDATA UV vertex_index,0,0 ENDIF local_ni=array_face(local_index).V1Normal IF local_tci>0 local_nx=array_normal(local_ni).x local_ny=array_normal(local_ni).y local_nz=array_normal(local_ni).z SET VERTEXDATA NORMALS vertex_index,local_nx,local_ny,local_nz ELSE SET VERTEXDATA NORMALS vertex_index,0,0,0 ENDIF SET INDEXDATA indice_index,vertex_index INC vertex_index : INC indice_index local_vi=array_face(local_index).V2Vertex local_vx=array_vertex(local_vi).x local_vy=array_vertex(local_vi).y local_vz=array_vertex(local_vi).z SET VERTEXDATA POSITION vertex_index,local_vx,local_vy,local_vz local_tci=array_face(local_index).V2TexCoord IF local_tci>0 local_u = array_texcoord(local_tci).u local_v = array_texcoord(local_tci).v SET VERTEXDATA UV vertex_index,0,local_u,-local_v ELSE SET VERTEXDATA UV vertex_index,0,0 ENDIF local_ni=array_face(local_index).V2Normal IF local_tci>0 local_nx=array_normal(local_ni).x local_ny=array_normal(local_ni).y local_nz=array_normal(local_ni).z SET VERTEXDATA NORMALS vertex_index,local_nx,local_ny,local_nz ELSE SET VERTEXDATA NORMALS vertex_index,0,0,0 ENDIF SET INDEXDATA indice_index,vertex_index INC vertex_index : INC indice_index local_vi=array_face(local_index).V3Vertex local_vx=array_vertex(local_vi).x local_vy=array_vertex(local_vi).y local_vz=array_vertex(local_vi).z SET VERTEXDATA POSITION vertex_index,local_vx,local_vy,local_vz local_tci=array_face(local_index).V3TexCoord IF local_tci>0 local_u = array_texcoord(local_tci).u local_v = array_texcoord(local_tci).v SET VERTEXDATA UV vertex_index,0,local_u,-local_v ELSE SET VERTEXDATA UV vertex_index,0,0 ENDIF local_ni=array_face(local_index).V3Normal IF local_tci>0 local_nx=array_normal(local_ni).x local_ny=array_normal(local_ni).y local_nz=array_normal(local_ni).z SET VERTEXDATA NORMALS vertex_index,local_nx,local_ny,local_nz ELSE SET VERTEXDATA NORMALS vertex_index,0,0,0 ENDIF SET INDEXDATA indice_index,vertex_index INC vertex_index : INC indice_index
NEXT UNLOCK VERTEXDATA
CALCULATE OBJECT BOUNDS ObjectID ENDFUNCTION
rem used to parse a float out of the obj file FUNCTION GetFloatFromString(thisString$,Position) LOCAL local_length AS INTEGER LOCAL local_index AS INTEGER LOCAL local_done AS INTEGER LOCAL local_string AS STRING LOCAL local_float AS FLOAT local_string="" local_done=0 local_length=LEN(thisString$) REPEAT Position=Position+1 IF MID$(thisString$,Position)<>" " local_string=local_string+MID$(thisString$,Position) ELSE gThisStringPosition=Position local_done=1 ENDIF UNTIL (Position=local_length) OR (local_done=1) local_float=VAL(local_string) ENDFUNCTION local_float
rem used to parse an integer out of the obj file FUNCTION GetIntegerFromString(thisString$,Position) LOCAL local_length AS INTEGER LOCAL local_index AS INTEGER LOCAL local_string AS STRING LOCAL local_int AS INTEGER local_string="" local_done=0 local_length=LEN(thisString$)
rem In case of "f v1/vt1 v2/vt2 v3/vt3 ...", return 0 for normal indice IF (gIndiceStep=3) IF (Position>=local_length) EXITFUNCTION 0 ELSE IF (MID$(thisString$,Position)=" ") EXITFUNCTION 0 ENDIF ENDIF ENDIF rem In case of "f v1 v2 v3 v4 ..." IF (gIndiceStep=2) AND (MID$(thisString$,Position)=" ") gThisStringPosition=Position EXITFUNCTION 0 ENDIF rem In case of "f v1//vn1 v2//vn2 v3//vn3 ...", return 0 for texture coordinates indice IF (gIndiceStep=2) AND (MID$(thisString$,Position)="/") AND (MID$(thisString$,Position+1)="/") gThisStringPosition=Position+1 EXITFUNCTION 0 ENDIF rem if string position > string length then nothing left to process IF (Position>=local_length) THEN EXITFUNCTION 0 REPEAT Position=Position+1 IF (MID$(thisString$,Position)<>" ") AND (MID$(thisString$,Position)<>"/") local_string=local_string+MID$(thisString$,Position) ELSE gThisStringPosition=Position local_int=VAL(local_string) EXITFUNCTION local_int ENDIF UNTIL Position>=local_length gThisStringPosition=Position local_int=VAL(local_string) ENDFUNCTION local_int
rem find unused object ID Function GetNewObjectID() ObjectID=0 repeat inc ObjectID until object exist(ObjectID)=0 EndFunction ObjectID
rem find unused image ID Function GetNewImageID() imageID=0 repeat inc imageID until image exist(imageID)=0 EndFunction imageID
|