I recommend using this method rather than .X or .b3d, because you get direct access to all the information the editor saves. Entity properties are stored in the entity name. You can use KeyValue$(entity,keyname$) to retrieve keyvalues. For example, KeyValue$(entity,"classname") might return "light".
If Windowed3D() Graphics3D 640,480,16,2 Else Graphics 640,480,16,1
SetBuffer BackBuffer()
cam=CreateCamera()
CameraRange cam,1,10000
TurnEntity cam,0,35,0
MoveEntity cam,0,200,-1500
CameraZoom cam,1.5
CreateLight()
map=LoadCSM("..\..\maps\bedroom.csm",CurrentDir()+"..\..\textures\")
While Not KeyHit(1)
RotateEntity map,0,MilliSecs()/100.0,0
RenderWorld
Flip
Wend
End
;=================================================
;=================================================
Function LoadCSM(file$,texturepath$="")
f=ReadFile(file)
If Not f Return
ChangeDir FileDir(file)
lightmapbank=CreateBank()
texturebank=CreateBank()
;Version
version=ReadInt(f)
If version<>4
CloseFile f
Return
EndIf
map=CreatePivot()
;Groups
DebugLog groupcount+" groups"
groupcount=ReadInt(f)
For n=1 To groupcount
flags=ReadInt(f)
group=ReadInt(f)
Properties$=readstringn(f)
r=ReadInt(f)
g=ReadInt(f)
b=ReadInt(f)
Next
;Lightmaps
lightmapcount=ReadInt(f)
DebugLog lightmapcount+" lightmaps"
For n=1 To lightmapcount
w=ReadInt(f)
h=ReadInt(f)
texture=CreateTexture(w,h)
TextureCoords texture,1
ResizeBank lightmapbank,BankSize(lightmapbank)+4
PokeInt lightmapbank,BankSize(lightmapbank)-4,texture
LockBuffer TextureBuffer(texture)
For ty=0 To h-1
For tx=0 To w-1
hue=ReadInt(f)
WritePixelFast tx,ty,hue,TextureBuffer(texture)
Next
Next
UnlockBuffer TextureBuffer(texture)
Next
;Meshes
meshcount=ReadInt(f)
DebugLog meshcount+" meshes"
For n=1 To meshcount
flags=ReadInt(f)
group=ReadInt(f)
properties$=readstringn(f)
r=ReadInt(f)
g=ReadInt(f)
b=ReadInt(f)
x#=ReadFloat(f)
y#=ReadFloat(f)
z#=ReadFloat(f)
facecount=ReadInt(f)
DebugLog facecount+" surfaces."
mesh=CreateMesh(map)
NameEntity mesh,properties
PositionEntity mesh,x,y,z
;Surfaces
For s=1 To facecount
flags=ReadInt(f)
texturefile$=readstringn(f)
lightmapindex=ReadInt(f)
offsetu#=ReadFloat(f)
offsetv#=ReadFloat(f)
scaleu#=ReadFloat(f)
scalev#=ReadFloat(f)
rotation#=ReadFloat(f)
vertexcount=ReadInt(f)
DebugLog vertexcount+" vertices"
trianglecount=ReadInt(f)
DebugLog trianglecount+" triangles"
linecount=ReadInt(f)
surf=CreateSurface(mesh)
brush=CreateBrush()
BrushFX brush,2
texturefile=Lower(texturefile)
texture=retrievetexture(texturepath+texturefile,texturebank)
If texture BrushTexture brush,texture
If lightmapindex>0 And lightmapindex*4<=BankSize(lightmapbank)
lightmap=PeekInt(lightmapbank,(lightmapindex-1)*4)
If lightmap
BrushTexture brush,lightmap,0,1
BrushFX brush,3
EndIf
EndIf
PaintSurface surf,brush
FreeBrush brush
;Vertices
For v=0 To vertexcount-1
x#=ReadFloat(f)
y#=ReadFloat(f)
z#=ReadFloat(f)
nx#=ReadFloat(f)
ny#=ReadFloat(f)
nz#=ReadFloat(f)
r=ReadInt(f)
g=ReadInt(f)
b=ReadInt(f)
u0#=ReadFloat(f)
v0#=ReadFloat(f)
w0#=ReadFloat(f)
u1#=ReadFloat(f)
v1#=ReadFloat(f)
w1#=ReadFloat(f)
TFormPoint x,y,z,0,mesh
AddVertex surf,TFormedX(),TFormedY(),TFormedZ(),u0,-v0
VertexColor surf,v,r,g,b
VertexTexCoords surf,v,u1,-v1,0,1
VertexNormal surf,v,nx,ny,nz
Next
;Triangles
For t=0 To trianglecount-1
a=ReadInt(f)
b=ReadInt(f)
c=ReadInt(f)
AddTriangle surf,a,c,b
Next
For l=0 To linecount-1
a=ReadInt(f)
b=ReadInt(f)
Next
Next
Next
;Point Entities
entitycount=ReadInt(f)
DebugLog entitycount+" entities"
For n=1 To entitycount
flags=ReadInt(f)
group=ReadInt(f)
properties$=readstringn(f)
x#=ReadFloat(f)
y#=ReadFloat(f)
z#=ReadFloat(f)
entity=CreatePivot(map)
NameEntity entity,properties
PositionEntity entity,x,y,z
Next
;Free textures
For n=0 To BankSize(lightmapbank)-1 Step 4
FreeTexture PeekInt(lightmapbank,n)
Next
FreeBank lightmapbank
For n=0 To BankSize(texturebank)-1 Step 8
FreeBank PeekInt(texturebank,n)
FreeTexture PeekInt(texturebank,n+4)
Next
FreeBank texturebank
CloseFile f
Return map
End Function
;Read a null-terminated string
Function ReadStringN$(f,maxlength=0)
Repeat
ch=ReadByte(f)
If ch=0 Return t$
If maxlength
If Len(t$)=maxlength Return t$+Chr(ch)
EndIf
t$=t$+Chr$(ch)
Forever
End Function
;Return a loaded texture
Function RetrieveTexture(file$,bank)
For n=0 To BankSize(bank)-1 Step 8
namebank=PeekInt(bank,n)
s$=""
For b=0 To BankSize(namebank)-1
s=s+Chr(PeekByte(namebank,b))
Next
If s=file Return PeekInt(bank,n+4)
Next
ResizeBank bank,BankSize(bank)+8
namebank=CreateBank(Len(file))
For b=0 To BankSize(namebank)-1
PokeByte namebank,b,Asc(Mid(file,b+1))
Next
DebugLog "Loading texture "+Chr(34)+CurrentDir()+file+Chr(34)
PokeInt bank,BankSize(bank)-8,namebank
texture=LoadTexture(file)
If Not texture DebugLog "Failed to load texture "+Chr(34)+CurrentDir()+file+Chr(34)
PokeInt bank,BankSize(bank)-4,texture
Return texture
End Function
;Get the file part of a file path
Function FileName$(file$,ext=1)
file=Replace(file,"/","\")
Repeat
p=Instr(file,"\")
If p
file=Right(file,Len(file)-p)
Else
Exit
EndIf
Forever
If Not ext
p=Instr(file,".")
If p file=Left(file,p-1)
EndIf
Return file
End Function
;Get the directory of a file path
Function FileDir$(file$)
file=Replace(file,"/","\")
oldp=1
Repeat
p=Instr(file,"\",oldp)
If p
oldp=p+1
Else
file=Left(file,oldp-1)
Exit
EndIf
Forever
Return file
End Function
;Parsing function
Function Piece$(s$,entry,char$=" ")
While Instr(s,char+char)
s=Replace(s,char+char,char)
Wend
For n=1 To entry-1
p=Instr(s,char)
s=Right(s,Len(s)-p)
Next
p=Instr(s,char)
If p<1
a$=s
Else
a=Left(s,p-1)
EndIf
Return a
End Function
;Function for retrieving entity properties
;[ "light"=KeyValue(entity,"classname") ]
Function KeyValue$(entity,key$)
properties$=EntityName(entity)
key$=Lower(key)
Repeat
p=Instr(properties,Chr(10))
If p test$=(Left(properties,p-1)) Else test=properties
testkey$=Piece(test,1,"=")
testkey=Trim(testkey)
testkey=Replace(testkey,Chr(34),"")
testkey=Lower(testkey)
If testkey=key
value$=Piece(test,2,"=")
value$=Trim(value$)
value$=Replace(value$,Chr(34),"")
Return value
EndIf
If Not p Return
properties=Right(properties,Len(properties)-p)
Forever
End Function
|