;vividgl-3d lite
;
;(c)antony wells.
;
;---[ entity module ] -[core]

Global glemesh =1,glelight=2,glepivot=3,glecamera=4
Type ent
	Field x#,y#,z#,oldx#,oldy#,oldz#
	Field pt#,yw#,rl#,isanim
	Field r#,g#,b#,a# 
	Field dr#,dg#,db#,da#,pindex
	Field sr#,sg#,sb#
	Field etype,spec#,emis#
	Field name$,blendmode
	Field vpiv,hpiv,lodlevel#,lodfactor#
	Field sdat.sdat[glmaxspe],sc 
	Field fx.fx,hide,dynamic
	Field hlevel,shareanims
	Field cullmode,WireFrame
	Field parent.ent,child.ent[255],childc
	Field colormode,disableshaders
	Field pickmode,response,mode
	Field xdir#,ydir#,zdir#,colmod
	Field lasthit,lastcols
	Field realent,b3dcol.b3dcol
	Field sim.sim_obj,sim_state,sim_mat
	Field bound.bound,hull.ent,convex
End Type

Function entity_updatebound(entity,meth=bound_cube)
Local sx#,sy#,sz#,bx#,by#,bz#
	in.ent=Object.ent(entity)
	bs#=0
	If in\bound=Null
		in\bound=New bound
	EndIf
	bound.bound=in\bound
	For j=0 To in\sc-1
		vbank=in\sdat[j]\cverts
		voff=0
		For k=0 To in\sdat[j]\vc-1
			x#=PeekFloat(vbank,voff)
			y#=PeekFloat(vbank,voff+4)
			z#=PeekFloat(vbank,voff+8)
			tx#=tx#+x
			ty#=ty#+y
			tz#=tz+z
			Select meth
			Case bound_box
				If Abs(x)>bs bs=Abs(x)
				If Abs(y)>bs bs=Abs(y)
				If Abs(z)>bs bs=Abs(z)
			Case bound_cube
				If x<sx sx=x
				If x>bx bx=x
				If y<sy sy=y
				If y>by by=y
				If z<sz sz=z
				If z>bz bz=z
			End Select
			voff=voff+12
		Next
		tv=tv+in\sdat[j]\vc;-1
	Next
	cx#=tx/tv
	cy#=ty/tv
	cz#=tz/tv
	Select meth
	Case bound_box
		bs=bs+0.05
		bound\size=bs*2
		bound\x=cx-bs
		bound\y=cy-bs
		bound\z=cz-bs
		bound\cx=cx
		bound\cy=cy
		bound\cz=cz
		bound\bsize=bs
		bound\w=bs*2
		bound\h=bs*2
		bound\d=bs*2
	Case bound_cube
		bound\x=sx
		bound\y=sy
		bound\z=sz
		bound\w=(bx-sx)
		bound\h=(by-sy)
		bound\d=(bz-sz)
		bound\x=sx+bound\w/2.0
		bound\y=sy+bound\h/2.0
		bound\z=sz+bound\d/2.0
	
End Select
	If bound\w>bound\h And bound\w>bound\d
		bound\size=bound\w
	Else
		If bound\h>bound\w And bound\h>bound\d
			bound\size=bound\h
		Else
			bound\size=bound\d
		EndIf
	EndIf
End Function

Function countentities()
	For ent.ent=Each ent
		ec=ec+1
	Next
	Return ec
End Function

Function getentity(index=0)
	For ent.ent=Each ent
		ec=ec+1
		If ec=>index Return Handle(ent)
	Next
End Function

Function findentity(name$,exact=False)
	For ent.ent =Each ent
		If exact
			If ent\name=name Return Handle(ent)
		Else
			If Instr(Lower(ent\name),Lower(name)) Return Handle(ent)
		EndIf
	Next
End Function

Function isentity(entity)
	Return Not (Object.ent(entity)=Null)
End Function

Function glBlitzPivot(entity)
	in.ent=Object.ent(entity)
	Return in\vpiv
End Function

Function Entity_Name(entity,name$)
	in.ent=Object.ent(entity)
	in\name=name
End Function

Function Entity_GetName$(entity)
	in.ent=Object.ent(entity)
	Return in\name
End Function

Function Entity_ColorMode(entity,glmode=Graphics_Colormode)
	in.ent=Object.ent(entity)
	in\colormode=glmode
End Function

Function Entity_GetColorMode(entity)
	in.ent=Object.ent(entity)
	Return in\colormode
End Function

Const Graphics_Colormode=0,Surface_Vertexmode=1

Function Prefab_Sphere(size#=1,segments=8,parent=0)
	mesh=Entity_ConvB3D( CreateSphere(segments))
	Entity_ScaleMesh(mesh,size,size,size)
	Entity_UpdateNormals( mesh)
	Return mesh
End Function

Function glentityparent(entity,parent,globalpivot=False)
	If parent=0 Return 
	in.ent=Object.ent(entity)
	par.ent=Object.ent(parent)
	If par=Null Return
	par\child[par\childc]=in
	par\childc=par\childc+1
	in\pindex=par\childc-1
	in\parent=par 
	EntityParent in\vpiv,par\vpiv,globalpivot
End Function 

Function entity_purgetextures(entity)
	in.ent=Object.ent(entity)
	For j=0 To in\sc-1
		For k=0 To in\sdat[j]\texc-1
			in\sdat[j]\tex[k]=0
		Next
		in\sdat[j]\texc=0
	Next
End Function 

Function Prefab_Cube(size#=1,parent=0,globalpivot=True)
	mesh=Entity_ConvB3D( CreateCube())
	Entity_ScaleMesh(mesh,size,size,size)
	Entity_UpdateNormals( mesh)
	glentityparent(mesh,parent,globalpivot)
	Return mesh
End Function

Function Entity_Pivot(parent=0,globalpivot=False)
	out.ent=New ent
	out\vpiv=CreatePivot()
	glentityparent(Handle(out),parent,globalpivot)
	Return Handle(out)
End Function

Function Entity_Free(entity)
	in.ent=Object.ent(entity)
	FreeEntity in\vpiv
	If in\hpiv<>0 FreeEntity in\hpiv
	If in\parent<>Null
		in\parent\child[in\pindex]=in\parent\child[in\parent\childc-1]
		in\parent\childc=in\parent\childc-1
	EndIf
	For j=0 To in\sc-1
		FreeBank in\sdat[j]\cverts
		FreeBank in\sdat[j]\ctris
		FreeBank in\sdat[j]\cnorm
		FreeBank in\sdat[j]\ccol
		For c=0 To in\sdat[j]\uvsets-1
			FreeBank in\sdat[j]\cuv[c]
		Next
		If in\sdat[j]\cmesh<>0 glDeleteLists in\sdat[j]\cmesh,1
		Delete in\sdat[j]
	Next
	Delete in
End Function

Function entity_noparent(entity)
in.ent=Object.ent(entity)
If in\parent<>Null
		in\parent\child[in\pindex]=in\parent\child[in\parent\childc-1]
		in\parent\childc=in\parent\childc-1
		in\parent=Null
	EndIf
End Function 

Dim pmap#(0,0,0)

Function terrain_create(w#,d#,xsegs,ysegs,texture,optimize=True,lod#=0) ;0=best quality, higher =lower quality.
	mesh=Entity_Create(1,2)
	surf=Entity_GetSurface(mesh,0)
	Surface_Lock(surf)
	xp=w/xdiv
	zp=d/zdiv
	tw#=w*xsegs
	td#=d*ysegs
	mw#=tw/2.
	md#=td/2.
	ax#=-mw
	az#=-md
	au#=0
	av#=0
	ui#=1.0/xsegs
	vi#=1.0/ysegs
	texw#=Texture_Width(texture)
	texh#=Texture_Height(texture)
	pxi#=texw/Float(xsegs)
	pyi#=texh/Float(ysegs)
	px#=0
	py#=0
Dim pmap#(xsegs+5,ysegs+5,10)
	For x=1 To xsegs
	For z=1 To ysegs
		cv=Texture_PickRed(texture,px,py)+Texture_PickGreen(texture,px,py)+Texture_PickBlue(texture,px,py)
		ph#=cv/9.
	
		pmap(x,z,3)=ph
		pmap(x,z,4)=ax
		pmap(x,z,5)=az
		pmap(x,z,6)=av
		pmap(x,z,7)=au
		az=az+d
		av=av+vi
		py=py+pyi
	Next
	py=0
	domore=0
	px=px+pxi
		az=-md
		au=au+ui
		av=0
		ax=ax+w
		rl=0
	Next
	For x=1 To xsegs
	For y=1 To ysegs
		base#=pmap(x,y,3)
		noise#=0
		realv#=0
		For cx=-2 To 2
		For cy=-2 To 2
			rx=x+cx
			ry=y+cy
			If (rx>0) And (ry>0) And (rx<(xsegs+1)) And (ry<(ysegs+1))
				noise#=noise+Abs(pmap(rx,ry,3)-base)
				realv=realv+pmap(rx,ry,3)
			EndIf
			
		Next
		Next
		noise=noise/16.
		realv=realv/25
 	If noise>5 Or x>xsegs-2 Or y>ysegs-2 Or x<3 Or y<3
			pmap(x,y,1)=Surface_Vertex( pmap(x,y,4),base,pmap(x,y,5),1,1,1,1)
			pmap(x,y,2)=True
			Surface_VertexUV pmap(x,y,1),pmap(x,y,6),pmap(x,y,7),0,0
			cv=base*9
			cv=cv/3
			Surface_VertexColor pmap(x,y,1),cv,cv,cv,1
			lastvert=pmap(x,y,1)
		Else
			pmap(x,y,1)=lastvert
		EndIf
	Next
	lastvert=0
	sy=0
	tf=0
	Next
	For x=1 To xsegs-1
	For y=1 To ysegs-1
		v1=pmap(x,y,1)
		v2=pmap(x+1,y,1)
		v3=pmap(x,y+1,1)
		If v1<>v2 And v1<>v3 And v2<>v3
			Surface_Triangle( v1,v2,v3)
		EndIf
		v1=pmap(x,y+1,1)
		v2=pmap(x+1,y,1)
		v3=pmap(x+1,y+1,1)
		If v1<>v2 And v1<>v3 And v2<>v3
			Surface_Triangle( v1,v2,v3)
		EndIf
	Next
	sy=0
	tf=0
	Next
	Surface_Unlock()
	Dim pmap(0,0,0) 
	entity_updatebound(mesh)
	Return mesh
End Function

Function prefab_patch(w#,d#,xsegs,ysegs)
	mesh=Entity_Create(1,2)
	surf=Entity_GetSurface(mesh,0)
	Surface_Lock(surf)
	xp=w/xdiv
	zp=d/zdiv
	tw#=w*xsegs
	td#=d*ysegs
	mw#=tw/2.
	md#=td/2.
	ax#=-mw
	az#=-md
	au#=0
	av#=0
	ui#=0.2
	vi#=0.2
Dim pmap(xsegs+5,ysegs+5,4) 
	For x=1 To xsegs
	For z=1 To ysegs
		pmap(x,z,1)=Surface_Vertex( ax#,0,az#,1,1,1,1)
		Surface_VertexUV pmap(x,z,1),au,av,0,0
		az=az+d
		av=av+vi
	Next
		az=-md
		au=au+ui
		av=0
		ax=ax+w
	Next
	For x=1 To xsegs-1
	For y=1 To ysegs-1
		Surface_Triangle( pmap(x,y+1,1),pmap(x+1,y,1),pmap(x,y,1))
		Surface_Triangle( pmap(x+1,y+1,1),pmap(x+1,y,1),pmap(x,y+1,1))
	Next
	Next
	Surface_Unlock()
	Dim pmap(0,0,0) 
	entity_updatebound(mesh)
	Return mesh
End Function

Function Prefab_Quad(w#,h#)
	mesh=Entity_Create(1)
	surf=Entity_GetSurface(mesh,0)
	Surface_Lock(surf)
	w2#=w/2
	h2#=h/2
	v0=Surface_Vertex(-w2,-h2,0,0,0)
	v1=Surface_Vertex(-w2,h2,0,0,1)
	v2=Surface_Vertex(w2,-h2,0,1,0)
	v3=Surface_Vertex(w2,h2,0,1,1)
	Surface_Triangle(v0,v1,v2)
	Surface_Triangle(v1,v2,v3)
	Surface_Triangle(v2,v1,v0)
	Surface_Triangle(v3,v2,v1)
	Surface_Unlock()
	Return mesh
End Function

Function Entity_Chase(entity,relative,x#,y#,z#,pointat=True,speed#=0.35,smartchase=True)
	in.ent=Object.ent(entity)
	rel.ent=Object.ent(relative)
	TFormPoint x,y,z,rel\vpiv,0
	Entity_Position(entity,in\x+(TFormedX()-in\x)*speed,in\y+(TFormedY()-in\y)*speed,in\z+(TFormedZ()-in\z)*speed)
	If pointat 
		Entity_Point(entity,relative)
		Entity_Rotate(entity,EntPi(entity),EntYa(entity),0)
	EndIf
End Function

Function entity_tricount(entity)
	in.ent=Object.ent(entity)
	For j=0 To in\sc-1
		out=out+in\sdat[j]\tc
	Next
	Return out
End Function

Function Entity_Position(entity,x#,y#,z#,globalposition=True)
	in.ent =Object.ent(entity)
	If in=Null RuntimeError "entity does not exist"
	PositionEntity in\vpiv,x,y,z,globalposition
	in\x=EntityX(in\vpiv,True)
	in\y=EntityY(in\vpiv,True)
	in\z=EntityZ(in\vpiv,True) 
	If in\etype =glelight esys\changed=True
	If in\childc>0 glupdatechildren(in)
End Function

Function EntX#(entity,globalx=True)
	in.ent=Object.ent(entity)
	If globalx
		Return EntityX(in\vpiv,True)
	Else
		Return EntityX(in\vpiv,False)
	EndIf
End Function

Function EntY#(entity,globaly=True)
	in.ent=Object.ent(entity)
	If globaly
		Return EntityY(in\vpiv,True)
	Else
		Return EntityY(in\vpiv,False)
	EndIf
End Function

Function EntZ#(entity,globalz=True)
	in.ent=Object.ent(entity)
	If globalz
		Return EntityZ(in\vpiv,True)
	Else
		Return EntityZ(in\vpiv,False)
	EndIf
End Function

Function Entity_Alpha(entity,alpha#=1)
	in.ent=Object.ent(entity)
	in\a=alpha
	If alpha<1.0 Entity_Blend(entity,glalpha)
End Function

Function Entity_Blend(entity,blend=glnormal)
	in.ent=Object.ent(entity)
	in\blendmode=blend
End Function

Const glnormal=0,gladd=2,glalpha=3

Function Entity_Rotate(entity,pitch#,yaw#,roll#,globalrotate=True)
	in.ent =Object.ent(entity)
	in\pt =pitch
	in\yw =yaw
	in\rl =roll
	RotateEntity in\vpiv,pitch,yaw,roll,globalrotate
	If in\childc>0 glupdatechildren(in)
End Function

Function Entity_Texture(entity,texture,index=-1)
in.ent=Object.ent(entity)
	For s=0 To in\sc-1
		Surface_Texture(Handle(in\sdat[s]),texture,index)
	Next
End Function

Const ShadeMode_Flat=0,ShadeMode_Smooth=1
;gl_smooth=1

Function Entity_Shading(entity,shademode)
	in.ent =Object.ent(entity)
	Select shademode
		Case 1 
			in\fx\shade=gl_smooth
		Case 0
			in\fx\shade=gl_flat
	End Select
End Function

Function glentityzmode(entity,zmode)
	in.ent =Object.ent(entity)
	Select zmode
		Case 1
			in\fx\depthtest=gl_depth_test
	End Select
End Function

Function glentityzfunc(entity,zfunc)
	in.ent =Object.ent(entity)
	Select zmode
		Case 1
			in\fx\depthfunc=gl_less
	End Select
End Function

Function Entity_Exists(entity)
	Return Object.ent(entity)<>Null
End Function

Const glcompile=1,Surface_Vertexarrays=2,Surface_Vertexobjects=3 



Function Entity_ConvB3D(blitzmesh,uvsets=2,convertmethod=Entity_Createrender,loadcached=False,file$="",ofile=0,faildir$="",localcaches=False) ;converts a blitz mesh to a Entity_Create
	realent=Entity_Make()
	If realent=0 Return 
	srfc=CountSurfaces(blitzmesh)
	out.ent =New ent
	out\etype =glemesh
	out\realent=realent
	out\name=EntityName(blitzmesh)
	out\vpiv=CreatePivot()
	out\fx =glfx()
	out\sc=srfc
Select convertmethod 
Case Entity_Createrender
	For j=1 To srfc
		out\sdat[j-1] =New sdat
		realsrf=IN_Surface_Make()
		
		If realsrf=0 RuntimeError "surface creation failed. fatal b3d conversation error."
		IN_Entity_Surface(realent,srf,j-1)		
		lsurf.sdat=out\sdat[j-1]
		lsurf\realsrf=realsrf
			srf=GetSurface(blitzmesh,j)
			vertc=CountVertices(srf)
			tric=CountTriangles(srf)
			cverts=CreateBank(vertc*12)
			ctris=CreateBank(tric*12)
			cnorm=CreateBank(vertc*12)
			ccol=CreateBank(vertc*16)
			IN_Surface_SetVerts realsrf,cverts,vertc
			IN_Surface_SetTris realsrf,ctris,tric
			IN_Surface_SetColors realsrf,ccol
			IN_Surface_SetNormals realsrf,cnorm
			lsurf\cverts=cverts
			lsurf\ctris=ctris
			lsurf\cnorm=cnorm
			lsurf\ccol=ccol
			For vj=0 To uvsets-1
					lsurf\cuv[vj]=CreateBank(vertc*16)
					IN_Surface_SetCoords realsrf,lsurf\cuv[vj],vj
			Next
			lsurf\uvsets=uvsets
 			bs=GetSurfaceBrush(srf)
			If bs<>0
				For tj=0 To 3
					bt=GetBrushTexture(bs,tj)
					If bt<>0
						tn$=TextureName(bt)
					If tn=""
					Else
					If FileType(tn)=1
						texin=Texture_Load(tn)
						If texin=0 
						Else
							Surface_Texture(Handle(lsurf),texin)
							Texture_SetName(texin,tn)
							Texture_Blend(texin,2)
						EndIf
						EndIf
					EndIf
					FreeTexture bt
				EndIf
			Next
			FreeBrush bs
		EndIf
		For v=0 To CountVertices(srf)-1
				nv=Surface_Vertex(VertexX(srf,v),VertexY(srf,v),VertexZ(srf,v),255,0,0,1)
				If nv<>v RuntimeError "v>"+v+" nv>"+nv
				For vj=0 To uvsets-1
					Surface_VertexUV(v,VertexV(srf,v,vj),1.0-VertexU(srf,v,vj),0,vj)
				Next
				Surface_VertexNormals(v,VertexNX(srf,v),VertexNY(srf,v),VertexNZ(srf,v))
			Next
			For t=0 To CountTriangles(srf)-1
				Surface_Triangle(TriangleVertex(srf,t,0),TriangleVertex(srf,t,1),TriangleVertex(srf,t,2))
			Next
	Next
End Select
FreeEntity blitzmesh
entity_updatebound(Handle(out))
Return Handle(out)
End Function

Function Entity_Paint(entity,red#,green#,blue#,alpha#=1)
	in.ent=Object.ent(entity)
	For s=0 To in\sc-1
		ccol=in\sdat[s]\ccol
		For j=0 To in\sdat[s]\vc-1
			offset=j*16
			PokeFloat ccol,offset,red/255.
			PokeFloat ccol,offset+4,green/255.
			PokeFloat ccol,offset+8,blue/255.
			PokeFloat ccol,offset+12,alpha
		Next
	Next
End Function

Function Entity_CountSurfaces(entity)
	in.ent =Object.ent(entity)
	Return in\sc
End Function

Function Entity_GetSurface(entity,index=0)
	in.ent =Object.ent(entity)
	If in\sc
		Return Handle(in\sdat[index])
	EndIf
End Function

Function Entity_FindSurface(entity,name$,exact=False)
	ent.ent=Object.ent(entity)
	For j=0 To ent\sc-1
		If exact
			If ent\sdat[j]\name=name
				Return Handle(ent\sdat[j])
			EndIf
		Else
			If Instr(Lower(ent\sdat[j]\name),Lower(name)) Return Handle(ent\sdat[j])
		EndIf
	Next
End Function

Function Entity_Create(surfaces=0,uvsets=2)
	out.ent =New ent
	out\etype=glemesh
	If surfaces
		For j=0 To surfaces-1
			out\sdat[j]=Object.sdat(Surface_Create(uvsets))
		Next
		out\sc=surfaces
	EndIf
	out\vpiv=CreatePivot()
	out\fx=glfx()
	Return Handle(out)
End Function

Function Entity_AddSurface(entity,surface)
	in.ent=Object.ent(entity)
	If surface=0 RuntimeError "surface does not exist"
	srf.sdat=Object.sdat(surface)
	in\sdat[in\sc]=srf
	in\sc=in\sc+1
End Function

Function Entity_Copy(entity,sharelimbs=True) 
	in.ent=Object.ent(entity)
	out.ent=New ent
	Insert out After in 
	out\r=in\r
	out\g=in\g
	out\b=in\b
	out\sr=in\sr
	out\sg=in\sg
	out\sb=in\sb
	out\cullmode=in\cullmode
	out\vpiv=CreatePivot()
	out\hpiv=CreatePivot()
	out\etype=in\etype
	For j=0 To in\sc-1
		out\sdat[j]=in\sdat[j]
	Next
	out\sc=in\sc
	out\fx=glfx()
	If in\fx<>Null
		out\fx\fs=in\fx\fs
	EndIf
	Return Handle(out)
End Function

Function Entity_Turn(entity,pitch#,yaw#,roll#)
	in.ent=Object.ent(entity)
	in\pt=in\pt+pitch
	in\yw=in\yw+yaw
	in\rl=in\rl+roll
	If in\pt>360 in\pt=in\pt-360
	If in\pt<0 in\pt=360+in\pt
	If in\yw>360 in\yw=in\yw-360
	If in\yw<0 in\yw=360+in\yw
	If in\rl>360 in\rl=in\rl-360
	If in\rl<0 in\rl=360+in\rl
	RotateEntity in\vpiv,in\pt,in\yw,in\rl,True
End Function

Function glupdatechildren(in.ent) ;internal function
	For c=0 To in\childc-1
		child.ent=in\child[c]
		vpiv=child\vpiv
		child\x=EntityX(vpiv,True)
		child\y=EntityY(vpiv,True)
		child\z=EntityZ(vpiv,True)
		child\pt=EntityPitch(vpiv,True)
		child\yw=EntityYaw(vpiv,True)
		child\rl=EntityRoll(vpiv,True)
		glupdatechildren(in\child[c])
	Next
End Function

Function Entity_Translate(entity,x#,y#,z#,globaltranslate=True)
	in.ent=Object.ent(entity)
	TranslateEntity in\vpiv,x,y,z,globaltranslate
	in\oldx=in\x
	in\oldy=in\y
	in\oldz=in\z
	in\x=EntityX(in\vpiv,True)
	in\y=EntityY(in\vpiv,True)
	in\z=EntityZ(in\vpiv,True)
	If in\childc>0 glupdatechildren(in)
End Function

Function Entity_WireFrame(entity,enable=False)
	in.ent=Object.ent(entity)
	in\WireFrame=enable
End Function

Function Entity_Move(entity,x#,y#,z#)
	in.ent=Object.ent(entity)
	MoveEntity in\vpiv,-x,y,z
	in\x=EntityX(in\vpiv,True)
	in\y=EntityY(in\vpiv,True)
	in\z=EntityZ(in\vpiv,True)
	If in\childc>0 glupdatechildren(in)
End Function

Function Entity_Color(entity,r#,g#,b#)
	in.ent=Object.ent(entity)
	in\r=r/255.
	in\g=g/255.
	in\b=b/255.
End Function

Function Entity_Point(from,at,roll#=0)
	fromt.ent=Object.ent(from)
	att.ent=Object.ent(at)
	PointEntity fromt\vpiv,att\vpiv,0
	glupdatevpiv(from,False)
End Function

Function Entity_PointAt(from,x#,y#,z#,roll#=0)
	fromt.ent=Object.ent(from)
	att.ent=Object.ent(at)
	PositionEntity lookat,x,y,z
	PointEntity fromt\vpiv,lookat,roll
	glupdatevpiv(from,False)
End Function

Function glupdatevpiv(entin,position=True,rotation=True)
	ent.ent=Object.ent(entin)
	If position
		ent\x=EntityX(ent\vpiv,True)
		ent\y=EntityY(ent\vpiv,True)
		ent\z=EntityZ(ent\vpiv,True)
	End If
	If rotation
		ent\pt=EntityPitch(ent\vpiv,True)
		ent\yw=EntityYaw(ent\vpiv,True)
		ent\rl=EntityRoll(ent\vpiv,True)
	EndIf
End Function

Function Entity_ScaleMesh(entity,xscale#,yscale#,zscale#)
	in.ent =Object.ent(entity)
	For j=0 To in\sc-1
		cverts=in\sdat[j]\cverts
		For v=0 To in\sdat[j]\vc-1
			vertex=v*12
			PokeFloat cverts,vertex,PeekFloat(cverts,vertex)*xscale
			PokeFloat cverts,vertex+4,PeekFloat(cverts,vertex+4)*yscale
			PokeFloat cverts,vertex+8,PeekFloat(cverts,vertex+8)*zscale
		Next
	Next
End Function

Function Entity_Ambient(entity,red#,green#,blue#)
	in.ent=Object.ent(entity)
	in\r=red/255.
	in\g=green/255.
	in\b=blue/255.
End Function

Function Entity_Diffuse(entity,red#,green#,blue#)
	in.ent=Object.ent(entity)
	in\dr=red/255.
	in\dg=green/255.
	in\db=blue/255.
End Function

Function entity_distance(entity1,entity2)
	ent1.ent=Object.ent(entity1)
	ent2.ent=Object.ent(entity2)
	Return EntityDistance( ent1\vpiv,ent2\vpiv)
End Function

Function Entity_Specular(entity,red#,green#,blue#)
	in.ent=Object.ent(entity)
	in\sr=red/255.
	in\sg=green/255.
	in\sb=blue/255.
End Function

Const CullMode_Front=0,CullMode_Back=1,CullMode_Disable=2

Function Entity_CullMode(entity,mode=CullMode_Back)
	in.ent=Object.ent(entity)
	in\cullmode=mode
End Function

Function EntPi#(entity,globalpitch=True)
	in.ent =Object.ent(entity)
	Return EntityPitch(in\vpiv,globalpitch)
End Function

Function EntYa#(entity,globalyaw=True)
	in.ent =Object.ent(entity)
	Return EntityYaw(in\vpiv,globalyaw)
End Function

Function EntRl#(entity,globalroll=True)
	in.ent =Object.ent(entity)
	Return EntityRoll(in\vpiv,globalroll)
End Function

Function glprepentity(in.ent,tris,verts)
	For s=0 To in\sc-1
		in\sdat[s]\cverts=CreateBank( verts*glvertsize)
		in\sdat[s]\cnorm=CreateBank( verts*glvertsize)
		in\sdat[s]\ccol=CreateBank( verts*glvertsize)
		in\sdat[s]\ctris=CreateBank( tris*gltrisize)
		in\sdat[s]\maxverts =verts
		in\sdat[s]\maxtris =tris
		in\sdat[s]\tc=tris
		in\sdat[s]\vc=0
	Next
End Function

Const glCullback=1,glCullfront=0,gldisablecull=2