Fixed pickmode constants. Now copies pickmode and types with TEntity.Copy.

Strict

Import BRL.LinkedList
Import MaxB3D.Math
Import "brush.bmx"
Import "collision.bmx"
Import "worldconfig.bmx"

Const PICKMODE_OFF			= 0
Const PICKMODE_SPHERE		= 1
Const PICKMODE_POLYGON	= 2
Const PICKMODE_BOX			= 3

Type TEntity
	Field _config:TWorldConfig
	Field _matrix:TMatrix=TMatrix.Identity(), _lockmatrix

	Field _name$
	Field _px#,_py#,_pz#
	Field _rx#,_ry#,_rz#
	Field _sx#,_sy#,_sz#

	Field _brush:TBrush=New TBrush

	Field _parent:TEntity,_childlist:TList=CreateList()
	Field _hidden,_order

	Field _collision:TCollision[]
	Field _oldx#,_oldy#,_oldz#
	Field _radiusx#,_radiusy#
	Field _boxx#,_boxy#,_boxz#,_boxwidth#,_boxheight#,_boxdepth#
	Field _type,_typelink:TLink
	Field _pickmode, _obscurer

	Field _cullradius#

	Field _alphaorder#

	Field _linklist:TList=CreateList()

	Method Init:TEntity(config:TWorldConfig,parent:TEntity)
		_config = config
		SetParent parent,False
		For Local l=EachIn Lists()
			AddLink _config.AddObject(Self,l)
		Next

		SetScale 1,1,1

		Return Self
	End Method

	Method Free()
		For Local child:TEntity=EachIn _childlist
			child.Free()
		Next
		For Local link:TLink=EachIn _linklist
			RemoveLink link
		Next
	End Method

	Method AddLink(link:TLink)
		_linklist.AddLast link
	End Method

	Method Lists[]()
		Return [WORLDLIST_ENTITY]
	End Method

	Method CopyData:TEntity(entity:TEntity)
		_config = entity._config
		Local pickmode, obscurer
		entity.GetPickMode pickmode,obscurer

		SetBrush entity.GetBrush()
		SetName entity.GetName()
		SetPickMode pickmode, obscurer
		SetType entity.GetType()
		Return Self
	End Method

	Method Copy_:TEntity(parent:TEntity=Null)
		Return New Self.CopyData(Self).Init(_config,parent)
	End Method

	Method Copy:TEntity(parent:TEntity=Null) Abstract

	Method AddParent(parent:TEntity)
		_parent=parent
		If parent
			_matrix.Overwrite parent._matrix
			parent._childlist.AddLast Self
		EndIf
	End Method

	Method GetParent:TEntity()
		Return _parent
	End Method
	Method SetParent(parent:TEntity,glob=True)
		Local gpx#,gpy#,gpz#
		Local grx#,gry#,grz#
		Local gsx#,gsy#,gsz#

		GetPosition gpx,gpy,gpz,True
		GetRotation grx,gry,grz,True
		GetScale gsx,gsy,gsz,True

		If _parent
			For Local entity:TEntity=EachIn _parent._childlist
				If entity=Self ListRemove(_parent._childlist,Self)
			Next
			_parent=Null
		EndIf

		_px=gpx;_py=gpy;_pz=gpz
		_rx=grx;_ry=gry;_rz=grz
		_sx=gsx;_sy=gsy;_sz=gsz

		If parent=Null UpdateMatrix(True);Return

		AddParent(parent)
		If glob
			SetPosition(gpx,gpy,gpz,True)
			SetRotation(grx,gry,grz,True)
			SetScale(gsx,gsy,gsz,True)
		Else
			UpdateMatrix(False)
		EndIf
	End Method

	Method CountChildren(recursive=False)
		Local count
		If recursive
			For Local child:TEntity=EachIn _childlist
				count:+child.CountChildren(True)
			Next
		EndIf
		Return _childlist.Count()+count
	End Method

	Method FindChild:TEntity(name$,recursive=False)
		For Local child:TEntity=EachIn _childlist
			If child.GetName()=name Return child
		Next
		If recursive
			For Local child:TEntity=EachIn _childlist
				Local entity:TEntity = child.FindChild(name, True)
				If entity Return entity
			Next
		EndIf
	End Method

	Method GetName$()
		Return _name
	End Method
	Method SetName(name$)
		_name=name
	End Method

	Method GetBrush:TBrush()
		Return _brush.Copy()
	End Method
	Method SetBrush(brush:TBrush)
		_brush.Load brush
	End Method

	Method GetColor(red Var,green Var,blue Var)
		Return _brush.GetColor(red,green,blue)
	End Method
	Method SetColor(red,green,blue)
		Return _brush.SetColor(red,green,blue)
	End Method

	Method GetAlpha#()
		Return _brush.GetAlpha()
	End Method
	Method SetAlpha(alpha#)
		_brush.SetAlpha(alpha)
	End Method

	Method GetShine#()
		Return _brush.GetShine()
	End Method
	Method SetShine(shine#)
		_brush.SetShine(shine)
	End Method

	Method GetTexture:TTexture(index)
		Return _brush.GetTexture(index)
	End Method
	Method SetTexture(texture:TTexture,index=0,frame=0)
		Return _brush.SetTexture(texture,index,frame)
	End Method

	Method GetFX()
		Return _brush.GetFX()
	End Method
	Method SetFX(fx)
		Return _brush.SetFX(fx)
	End Method

	Method GetBlend()
		Return _brush.GetBlend()
	End Method
	Method SetBlend(blend)
		Return _brush.SetBlend(blend)
	End Method

	Method GetShader:TShader()
		Return _brush.GetShader()
	End Method
	Method SetShader(shader:TShader)
		Return _brush.SetShader(shader)
	End Method

	Method GetScale(x# Var,y# Var,z# Var,glob=False)
		If glob
			x=_matrix._m[0,0]
			y=_matrix._m[1,1]
			z=_matrix._m[2,2]
		Else
			x=_sx;y=_sy;z=_sz
		EndIf
	End Method
	Method SetScale(x#,y#,z#,glob=False)
		_sx=x;_sy=y;_sz=z
		If glob=True And _parent<>Null
			Local entity:TEntity=Self
			Repeat
				_sx:/entity._parent._sx
				_sy:/entity._parent._sy
				_sz:/entity._parent._sz
				entity=entity._parent
			Until entity._parent=Null
		EndIf
		RefreshMatrix()
	End Method

	Method Transform(matrix:TMatrix,glob=False)
		SetMatrix matrix.Multiply(_matrix),glob
	End Method

	Method Turn(pitch#,yaw#,roll#,glob=False)
		_rx:+pitch;_ry:+yaw;_rz:+roll
		RefreshMatrix()
	End Method

	Method Point(target:Object,roll#=0.0)
		Local x#,y#,z#,tx#,ty#,tz#
		GetPosition x,y,z,True
		GetTargetPosition target,tx,ty,tz

		Local xdiff#=x-tx,ydiff#=y-ty,zdiff#=z-tz

		Local dist22#=Sqr((xdiff*xdiff)+(zdiff*zdiff))
		Local pitch#=ATan2(ydiff,dist22)
		Local yaw#=ATan2(xdiff,-zdiff)

		SetRotation pitch,yaw,roll,True
	End Method

	Method GetDistance#(target:Object)
		Local x#,y#,z#,tx#,ty#,tz#
		GetPosition x,y,z,True
		GetTargetPosition target,tx,ty,tz
		Return Sqr((x-tx)*(x-tx)+(y-ty)*(y-ty)+(z-tz)*(z-tz))
	End Method

	Function GetTargetPosition(target:Object,x# Var,y# Var,z# Var)
		Assert target,"Null target given."
		If TEntity(target) TEntity(target).GetPosition x,y,z,True
		If Float[](target)
			Local coords#[]=Float[](target)
			If coords.length>0 x=coords[0]
			If coords.length>1 y=coords[1]
			If coords.length>2 z=coords[2]
		EndIf
		Assert "Invalid target given."
	End Function

	Method GetRotation(pitch# Var,yaw# Var,roll# Var,glob=False)
		If glob
			_matrix.GetRotation pitch,yaw,roll
			pitch:*-1
			yaw:*-1
		Else
			pitch=_rx;yaw=_ry;roll=_rz
		EndIf
	End Method
	Method SetRotation(pitch#,yaw#,roll#,glob=False)
		_rx=pitch;_ry=yaw;_rz=roll
		If glob And _parent<>Null
			Local rx#,ry#,rz#
			_parent.GetRotation rx,ry,rz
			_rx:+rx;_ry:+ry;_rz:+rz
		EndIf
		RefreshMatrix()
	End Method

	Method GetPosition(x# Var,y# Var,z# Var,glob=False)
		x=_px;y=_py;z=_pz
		If glob _matrix.GetPosition x,y,z
	End Method
	Method SetPosition(x#,y#,z#,glob=False)
		_px=x;_py=y;_pz=z

		If glob And _parent<>Null
			Local px#,py#,pz#
			_parent.GetPosition px,py,pz,True
			_px:-px;_py:-py;_pz:-pz
		EndIf

		RefreshMatrix()
	End Method

	Method Move(x#,y#,z#)
		Local matrix:TMatrix=TMatrix.Identity()
		matrix=TMatrix.YawPitchRoll(-_ry,-_rx,_rz).Multiply(matrix)
		matrix=TMatrix.Translation(x,y,z).Multiply(matrix)

		matrix.GetPosition(x,y,z)
		_px:+x;_py:+y;_pz:+z

		RefreshMatrix()
	End Method

	Method Translate(x#,y#,z#,glob=True)
		If glob And _parent
			Local ax#,ay#,az#
			GetRotation ax,ay,az,True

			Local matrix:TMatrix=TMatrix.Roll(-az)
			matrix=matrix.Multiply(TMatrix.Pitch(-ax))
			matrix=matrix.Multiply(TMatrix.Yaw(-ay))
			matrix=matrix.Multiply(TMatrix.Translation(x,y,z))

			matrix.GetPosition x,y,z
		EndIf

		_px:+x;_py:+y;_pz:+z

		RefreshMatrix()
	End Method

	Method GetVisible()
		Local entity:TEntity=Self
		While entity<>Null
			If entity._hidden=True Return False
			entity=entity._parent
		Wend
		Return True
	End Method
	Method SetVisible(visible)
		_hidden=Not visible
	End Method

	Method GetOrder()
		Return _order
	End Method
	Method SetOrder(order)
		_order=order
	End Method

	Method GetCollisions:TCollision[]()
		Return _collision
	End Method

	Method GetRadius(x# Var,y# Var)
		x=_radiusx;y=_radiusy
	End Method
	Method SetRadius(x#,y#=-1)
		_radiusx=x;_radiusy=x
		If y>-1 _radiusy=y
	End Method

	Method GetBox(x# Var,y# Var,z# Var,width# Var,height# Var,depth# Var)
		x=_boxx;y=_boxy;z=_boxz
		width=_boxwidth;height=_boxheight;depth=_boxdepth
	End Method
	Method SetBox(x#,y#,z#,width#,height#,depth#)
		_boxx=x;_boxy=y;_boxz=z
		_boxwidth=width;_boxheight=height;_boxdepth=depth
	End Method

	Method Reset()
		_collision=Null
		GetPosition _oldx,_oldy,_oldz,True
	End Method

	Method GetType()
		Return _type
	End Method
	Method SetType(typ,recursive=False)
		If _typelink
			_linklist.Remove(_typelink)
			_typelink.Remove()
			_typelink=Null
		EndIf

		If typ>0
			If _config.CollisionType[typ]=Null _config.CollisionType[typ]=CreateList()
			_typelink=_config.CollisionType[typ].AddLast(Self)
			AddLink _typelink
		EndIf

		_type=typ
		GetPosition _oldx,_oldy,_oldz,True

		If recursive
			For Local child:TEntity=EachIn _childlist
				child.SetType typ,True
			Next
		EndIf
	End Method

	Method GetCullRadius#()
		Return Abs(_cullradius)
	End Method
	Method SetCullRadius(radius#)
		_cullradius=-radius
	End Method

	Method GetCullParams(x# Var,y# Var,z# Var,radius# Var)
		GetPosition x,y,z,True
		radius=GetCullRadius()
	End Method

	Method GetPickMode(mode Var, obscurer Var)
		mode = _pickmode
		obscurer = _obscurer
	End Method
	Method SetPickMode(mode, obscurer=True)
		_pickmode = mode
		_obscurer = obscurer
	End Method

	Method HasAlpha()
		Return _brush.HasAlpha()
	End Method

	Method GetMatrix:TMatrix(alternate=False,copy=True)
		If copy Return _matrix.Copy()
		Return _matrix
	End Method
	Method SetMatrix(matrix:TMatrix,glob=True)
		Local x#,y#,z#,pitch#,yaw#,roll#,sx#,sy#,sz#
		matrix.GetPosition x,y,z
		matrix.GetRotation pitch,yaw,roll
		matrix.GetScale sx,sy,sz

		LockMatrix
		SetPosition x,y,z,glob
		SetRotation pitch,yaw,roll,glob
		SetScale sx,sy,sz,glob
		UnlockMatrix
	End Method

	Method LockMatrix()
		_lockmatrix=True
	End Method
	Method UnlockMatrix()
		_lockmatrix=False
		RefreshMatrix()
	End Method

	Method RefreshMatrix()
		If _lockmatrix Return
		If _parent<>Null
			_matrix.Overwrite _parent._matrix
			UpdateMatrix False
		Else
			UpdateMatrix True
		EndIf

		For Local child:TEntity=EachIn _childlist
			child.RefreshMatrix()
		Next
	End Method

	Method UpdateMatrix(loadidentity)
		If loadidentity _matrix=TMatrix.Identity()
		_matrix=TMatrix.Translation(_px,_py,_pz).Multiply(_matrix)
		_matrix=TMatrix.YawPitchRoll(-_ry,-_rx,_rz).Multiply(_matrix)
		_matrix=TMatrix.Scale(_sx,_sy,_sz).Multiply(_matrix)
	End Method

	Method ObjectEnumerator:Object()
		Return TChildrenEnumerator.Create(_childlist)
	End Method
End Type

Type TChildrenEnumerator
	Field _children:TEntity[],_index=-1

	Function Create:TChildrenEnumerator(list:TList)
		Local enum:TChildrenEnumerator=New TChildrenEnumerator
		enum._children=TEntity[](list.ToArray())
		Return enum
	End Function

	Method HasNext()
		Return _index>=_children.length-1
	End Method

	Method NextObject:Object()
		_index:+1
		Return _children[_index]
	End Method
End Type

Strict

Import BRL.LinkedList
Import MaxB3D.Math
Import "brush.bmx"
Import "collision.bmx"
Import "worldconfig.bmx"

Const PICKMODE_OFF		= 1
Const PICKMODE_SPHERE	= 2
Const PICKMODE_POLYGON	= 3
Const PICKMODE_BOX		= 4

Type TEntity
	Field _config:TWorldConfig
	Field _matrix:TMatrix=TMatrix.Identity(), _lockmatrix

	Field _name$
	Field _px#,_py#,_pz#
	Field _rx#,_ry#,_rz#
	Field _sx#,_sy#,_sz#

	Field _brush:TBrush=New TBrush

	Field _parent:TEntity,_childlist:TList=CreateList()
	Field _hidden,_order

	Field _collision:TCollision[]
	Field _oldx#,_oldy#,_oldz#
	Field _radiusx#,_radiusy#
	Field _boxx#,_boxy#,_boxz#,_boxwidth#,_boxheight#,_boxdepth#
	Field _type,_typelink:TLink
	Field _pickmode, _obscurer

	Field _cullradius#

	Field _alphaorder#

	Field _linklist:TList=CreateList()

	Method Init:TEntity(config:TWorldConfig,parent:TEntity)
		_config = config
		SetParent parent,False
		For Local l=EachIn Lists()
			AddLink _config.AddObject(Self,l)
		Next

		SetScale 1,1,1

		Return Self
	End Method

	Method Free()
		For Local child:TEntity=EachIn _childlist
			child.Free()
		Next
		For Local link:TLink=EachIn _linklist
			RemoveLink link
		Next
	End Method

	Method AddLink(link:TLink)
		_linklist.AddLast link
	End Method

	Method Lists[]()
		Return [WORLDLIST_ENTITY]
	End Method

	Method CopyData:TEntity(entity:TEntity)
		SetBrush entity.GetBrush()
		SetName entity.GetName()
		Return Self
	End Method

	Method Copy_:TEntity(parent:TEntity=Null)
		Return New Self.CopyData(Self).Init(_config,parent)
	End Method

	Method Copy:TEntity(parent:TEntity=Null) Abstract

	Method AddParent(parent:TEntity)
		_parent=parent
		If parent
			_matrix.Overwrite parent._matrix
			parent._childlist.AddLast Self
		EndIf
	End Method

	Method GetParent:TEntity()
		Return _parent
	End Method
	Method SetParent(parent:TEntity,glob=True)
		Local gpx#,gpy#,gpz#
		Local grx#,gry#,grz#
		Local gsx#,gsy#,gsz#

		GetPosition gpx,gpy,gpz,True
		GetRotation grx,gry,grz,True
		GetScale gsx,gsy,gsz,True

		If _parent
			For Local entity:TEntity=EachIn _parent._childlist
				If entity=Self ListRemove(_parent._childlist,Self)
			Next
			_parent=Null
		EndIf

		_px=gpx;_py=gpy;_pz=gpz
		_rx=grx;_ry=gry;_rz=grz
		_sx=gsx;_sy=gsy;_sz=gsz

		If parent=Null UpdateMatrix(True);Return

		AddParent(parent)
		If glob
			SetPosition(gpx,gpy,gpz,True)
			SetRotation(grx,gry,grz,True)
			SetScale(gsx,gsy,gsz,True)
		Else
			UpdateMatrix(False)
		EndIf
	End Method

	Method CountChildren(recursive=False)
		Local count
		If recursive
			For Local child:TEntity=EachIn _childlist
				count:+child.CountChildren(True)
			Next
		EndIf
		Return _childlist.Count()+count
	End Method

	Method FindChild:TEntity(name$,recursive=False)
		For Local child:TEntity=EachIn _childlist
			If child.GetName()=name Return child
		Next
		If recursive
			For Local child:TEntity=EachIn _childlist
				Local entity:TEntity = child.FindChild(name, True)
				If entity Return entity
			Next
		EndIf
	End Method

	Method GetName$()
		Return _name
	End Method
	Method SetName(name$)
		_name=name
	End Method

	Method GetBrush:TBrush()
		Return _brush.Copy()
	End Method
	Method SetBrush(brush:TBrush)
		_brush.Load brush
	End Method

	Method GetColor(red Var,green Var,blue Var)
		Return _brush.GetColor(red,green,blue)
	End Method
	Method SetColor(red,green,blue)
		Return _brush.SetColor(red,green,blue)
	End Method

	Method GetAlpha#()
		Return _brush.GetAlpha()
	End Method
	Method SetAlpha(alpha#)
		_brush.SetAlpha(alpha)
	End Method

	Method GetShine#()
		Return _brush.GetShine()
	End Method
	Method SetShine(shine#)
		_brush.SetShine(shine)
	End Method

	Method GetTexture:TTexture(index)
		Return _brush.GetTexture(index)
	End Method
	Method SetTexture(texture:TTexture,index=0,frame=0)
		Return _brush.SetTexture(texture,index,frame)
	End Method

	Method GetFX()
		Return _brush.GetFX()
	End Method
	Method SetFX(fx)
		Return _brush.SetFX(fx)
	End Method

	Method GetBlend()
		Return _brush.GetBlend()
	End Method
	Method SetBlend(blend)
		Return _brush.SetBlend(blend)
	End Method

	Method GetShader:TShader()
		Return _brush.GetShader()
	End Method
	Method SetShader(shader:TShader)
		Return _brush.SetShader(shader)
	End Method

	Method GetScale(x# Var,y# Var,z# Var,glob=False)
		If glob
			x=_matrix._m[0,0]
			y=_matrix._m[1,1]
			z=_matrix._m[2,2]
		Else
			x=_sx;y=_sy;z=_sz
		EndIf
	End Method
	Method SetScale(x#,y#,z#,glob=False)
		_sx=x;_sy=y;_sz=z
		If glob=True And _parent<>Null
			Local entity:TEntity=Self
			Repeat
				_sx:/entity._parent._sx
				_sy:/entity._parent._sy
				_sz:/entity._parent._sz
				entity=entity._parent
			Until entity._parent=Null
		EndIf
		RefreshMatrix()
	End Method

	Method Transform(matrix:TMatrix,glob=False)
		SetMatrix matrix.Multiply(_matrix),glob
	End Method

	Method Turn(pitch#,yaw#,roll#,glob=False)
		_rx:+pitch;_ry:+yaw;_rz:+roll
		RefreshMatrix()
	End Method

	Method Point(target:Object,roll#=0.0)
		Local x#,y#,z#,tx#,ty#,tz#
		GetPosition x,y,z,True
		GetTargetPosition target,tx,ty,tz

		Local xdiff#=x-tx,ydiff#=y-ty,zdiff#=z-tz

		Local dist22#=Sqr((xdiff*xdiff)+(zdiff*zdiff))
		Local pitch#=ATan2(ydiff,dist22)
		Local yaw#=ATan2(xdiff,-zdiff)

		SetRotation pitch,yaw,roll,True
	End Method

	Method GetDistance#(target:Object)
		Local x#,y#,z#,tx#,ty#,tz#
		GetPosition x,y,z,True
		GetTargetPosition target,tx,ty,tz
		Return Sqr((x-tx)*(x-tx)+(y-ty)*(y-ty)+(z-tz)*(z-tz))
	End Method

	Function GetTargetPosition(target:Object,x# Var,y# Var,z# Var)
		Assert target,"Null target given."
		If TEntity(target) TEntity(target).GetPosition x,y,z,True
		If Float[](target)
			Local coords#[]=Float[](target)
			If coords.length>0 x=coords[0]
			If coords.length>1 y=coords[1]
			If coords.length>2 z=coords[2]
		EndIf
		Assert "Invalid target given."
	End Function

	Method GetRotation(pitch# Var,yaw# Var,roll# Var,glob=False)
		If glob
			_matrix.GetRotation pitch,yaw,roll
			pitch:*-1
			yaw:*-1
		Else
			pitch=_rx;yaw=_ry;roll=_rz
		EndIf
	End Method
	Method SetRotation(pitch#,yaw#,roll#,glob=False)
		_rx=pitch;_ry=yaw;_rz=roll
		If glob And _parent<>Null
			Local rx#,ry#,rz#
			_parent.GetRotation rx,ry,rz
			_rx:+rx;_ry:+ry;_rz:+rz
		EndIf
		RefreshMatrix()
	End Method

	Method GetPosition(x# Var,y# Var,z# Var,glob=False)
		x=_px;y=_py;z=_pz
		If glob _matrix.GetPosition x,y,z
	End Method
	Method SetPosition(x#,y#,z#,glob=False)
		_px=x;_py=y;_pz=z

		If glob And _parent<>Null
			Local px#,py#,pz#
			_parent.GetPosition px,py,pz,True
			_px:-px;_py:-py;_pz:-pz
		EndIf

		RefreshMatrix()
	End Method

	Method Move(x#,y#,z#)
		Local matrix:TMatrix=TMatrix.Identity()
		matrix=TMatrix.YawPitchRoll(-_ry,-_rx,_rz).Multiply(matrix)
		matrix=TMatrix.Translation(x,y,z).Multiply(matrix)

		matrix.GetPosition(x,y,z)
		_px:+x;_py:+y;_pz:+z

		RefreshMatrix()
	End Method

	Method Translate(x#,y#,z#,glob=True)
		If glob And _parent
			Local ax#,ay#,az#
			GetRotation ax,ay,az,True

			Local matrix:TMatrix=TMatrix.Roll(-az)
			matrix=matrix.Multiply(TMatrix.Pitch(-ax))
			matrix=matrix.Multiply(TMatrix.Yaw(-ay))
			matrix=matrix.Multiply(TMatrix.Translation(x,y,z))

			matrix.GetPosition x,y,z
		EndIf

		_px:+x;_py:+y;_pz:+z

		RefreshMatrix()
	End Method

	Method GetVisible()
		Local entity:TEntity=Self
		While entity<>Null
			If entity._hidden=True Return False
			entity=entity._parent
		Wend
		Return True
	End Method
	Method SetVisible(visible)
		_hidden=Not visible
	End Method

	Method GetOrder()
		Return _order
	End Method
	Method SetOrder(order)
		_order=order
	End Method

	Method GetCollisions:TCollision[]()
		Return _collision
	End Method

	Method GetRadius(x# Var,y# Var)
		x=_radiusx;y=_radiusy
	End Method
	Method SetRadius(x#,y#=-1)
		_radiusx=x;_radiusy=x
		If y>-1 _radiusy=y
	End Method

	Method GetBox(x# Var,y# Var,z# Var,width# Var,height# Var,depth# Var)
		x=_boxx;y=_boxy;z=_boxz
		width=_boxwidth;height=_boxheight;depth=_boxdepth
	End Method
	Method SetBox(x#,y#,z#,width#,height#,depth#)
		_boxx=x;_boxy=y;_boxz=z
		_boxwidth=width;_boxheight=height;_boxdepth=depth
	End Method

	Method Reset()
		_collision=Null
		GetPosition _oldx,_oldy,_oldz,True
	End Method

	Method GetType()
		Return _type
	End Method
	Method SetType(typ,recursive=False)
		If _typelink
			_linklist.Remove(_typelink)
			_typelink.Remove()
			_typelink=Null
		EndIf

		If typ>0
			If _config.CollisionType[typ]=Null _config.CollisionType[typ]=CreateList()
			_typelink=_config.CollisionType[typ].AddLast(Self)
			AddLink _typelink
		EndIf

		_type=typ
		GetPosition _oldx,_oldy,_oldz,True

		If recursive
			For Local child:TEntity=EachIn _childlist
				child.SetType typ,True
			Next
		EndIf
	End Method

	Method GetCullRadius#()
		Return Abs(_cullradius)
	End Method
	Method SetCullRadius(radius#)
		_cullradius=-radius
	End Method

	Method GetCullParams(x# Var,y# Var,z# Var,radius# Var)
		GetPosition x,y,z,True
		radius=GetCullRadius()
	End Method

	Method GetPickMode(mode Var, obscurer Var)
		mode = _pickmode
		obscurer = _obscurer
	End Method
	Method SetPickMode(mode, obscurer=True)
		_pickmode = mode
		_obscurer = obscurer
	End Method

	Method HasAlpha()
		Return _brush.HasAlpha()
	End Method

	Method GetMatrix:TMatrix(alternate=False,copy=True)
		If copy Return _matrix.Copy()
		Return _matrix
	End Method
	Method SetMatrix(matrix:TMatrix,glob=True)
		Local x#,y#,z#,pitch#,yaw#,roll#,sx#,sy#,sz#
		matrix.GetPosition x,y,z
		matrix.GetRotation pitch,yaw,roll
		matrix.GetScale sx,sy,sz

		LockMatrix
		SetPosition x,y,z,glob
		SetRotation pitch,yaw,roll,glob
		SetScale sx,sy,sz,glob
		UnlockMatrix
	End Method

	Method LockMatrix()
		_lockmatrix=True
	End Method
	Method UnlockMatrix()
		_lockmatrix=False
		RefreshMatrix()
	End Method

	Method RefreshMatrix()
		If _lockmatrix Return
		If _parent<>Null
			_matrix.Overwrite _parent._matrix
			UpdateMatrix False
		Else
			UpdateMatrix True
		EndIf

		For Local child:TEntity=EachIn _childlist
			child.RefreshMatrix()
		Next
	End Method

	Method UpdateMatrix(loadidentity)
		If loadidentity _matrix=TMatrix.Identity()
		_matrix=TMatrix.Translation(_px,_py,_pz).Multiply(_matrix)
		_matrix=TMatrix.YawPitchRoll(-_ry,-_rx,_rz).Multiply(_matrix)
		_matrix=TMatrix.Scale(_sx,_sy,_sz).Multiply(_matrix)
	End Method

	Method ObjectEnumerator:Object()
		Return TChildrenEnumerator.Create(_childlist)
	End Method
End Type

Type TChildrenEnumerator
	Field _children:TEntity[],_index=-1

	Function Create:TChildrenEnumerator(list:TList)
		Local enum:TChildrenEnumerator=New TChildrenEnumerator
		enum._children=TEntity[](list.ToArray())
		Return enum
	End Function

	Method HasNext()
		Return _index>=_children.length-1
	End Method

	Method NextObject:Object()
		_index:+1
		Return _children[_index]
	End Method
End Type


Added more retro functions.

Added more retro functions.

Strict

Rem
	bbdoc: Blitz3D style wrapper for MaxB3D
End Rem
Module MaxB3D.Retro
ModuleInfo "Author: Kevin Primm"
ModuleInfo "License: MIT"

Import MaxB3D.GLDriver
Import MaxB3D.D3D9Driver
Import MaxB3D.Primitives

Import MaxB3D.B3DCollision

Import MaxB3D.A3DSLoader
Import MaxB3D.B3DLoader
Import MaxB3D.MD2Loader
Import MaxB3D.XLoader

Import BRL.BMPLoader
Import BRL.JPGLoader
Import BRL.PNGLoader
Import BRL.TGALoader

Private
Global _currentworld:TWorld
Global _renderinfo:TRenderInfo = New TRenderInfo
Global tform_x#, tform_y#, tform_z#

Public

Function Graphics3D(width, height, depth = 32, mode = 0)
	Select mode
	Case 0
?Debug
		depth = 0
?Not Debug
		depth = 32
?
	Case 1
		depth = 32
	Case 2
		depth = 0
	End Select
	Graphics width,height,depth
End Function
' Dither
' WBuffer
' AntiAlias
Function Wireframe(enable)
	_currentworld.SetWireFrame enable
End Function
' HWMultiTex
Function AmbientLight(red, green, blue)
	_currentworld.SetAmbientLight red, green, blue
End Function
' ClearCollisions
' Collisions
Function UpdateWorld(speed# = 1.0)
	_currentworld.Update(speed)
End Function
Function RenderWorld(tween# = 1.0)
	_renderinfo = _currentworld.Render(tween)
End Function
' CaptureWorld
' ClearWorld
' LoaderMatrix
Function TrisRendered()
	Return _renderinfo.triangles
End Function

' CreateTexture
Function LoadTexture:TTexture(url:Object,flags=TEXTURE_COLOR)
	Return CurrentWorld().AddTexture(url,flags)
End Function
' LoadAnimTexture
Function FreeTexture(texture:TTexture)
	Return texture.Free()
End FUnction
' TextureBlend
Function TextureCoords(texture:TTexture, coords)
	Return texture.SetCoords(coords)
End Function
' ScaleTexture
' PositionTexture
' RotateTexture
Function TextureWidth(texture:TTexture)
	Local width,height
	texture.GetSize width,height
	Return width
End Function
Function TextureHeight(texture:TTexture)
	Local width,height
	texture.GetSize width,height
	Return height
End Function
' TextureName
' GetBrushTexture
Function ClearTextureFilters()
	Return _currentworld.ClearTextureFilters()
End Function
Function TextureFilter(text$, flags)
	Return _currentworld.AddTextureFilter(text, flags)
End Function
' SetCubeFace
' SetCubeMode

Function CreateBrush:TBrush(red=255,green=255,blue=255)
	Return _currentworld.AddBrush([red,green,blue])
End Function
Function CopyBrush:TBrush(brush:TBrush)
	Return brush.Copy()
End Function
Function BrushColor(brush:TBrush,red,green,blue)
	Return brush.SetColor(red,green,blue)
End Function
Function BrushAlpha(brush:TBrush,alpha#)
	Return brush.SetAlpha(alpha)
End Function
Function BrushShininess(brush:TBrush,shine#)
	Return brush.SetShine(shine)
End Function
Function BrushTexture(brush:TBrush,texture:TTexture,index=0,frame=0)
	Return brush.SetTexture(texture,index,frame)
End Function
Function BrushFX(brush:TBrush,fx)
	Return brush.SetFX(fx)
End Function
Function BrushBlend(brush:TBrush,fx)
	Return brush.SetBlend(fx)
End Function

Rem
' LoadBrush
' FreeBrush
' GetEntityBrush
' GetSurfaceBrush

' CreateMesh
' LoadMesh
' LoadAnimMesh
' CreateCube
' CreateSphere
' CreateCylinder
' CreateCone
' CopyMesh
' AddMesh
' FlipMesh
' PaintMesh
' LightMesh
' FitMesh
' ScaleMesh
' RotateMesh
' PositionMesh
' UpdateNormals
' MeshesIntersect
' MeshWidth
' MeshHeight
' MeshDepth
End Rem
Function CountSurfaces(mesh:TMesh)
	Return mesh.CountSurfaces()
End Function
Function GetSurface:TSurface(mesh:TMesh,index)
	Return mesh.GetSurface(index-1)
End Function
Rem

' CreateSurface
' PaintSurface
' ClearSurface
' FindSurface
' AddVertex
' AddTriangle
' VertexCoords
' VertexNormal
' VertexColor
' VertexTexCoords
End Rem
Function CountVertices(surface:TSurface)
	Return surface.CountVertices()
End Function
Function CountTriangles(surface:TSurface)
	Return surface.CountTriangles()
End Function
Function VertexX#(surface:TSurface, index)
	Local x#,y#,z#
	surface.GetCoords index,x,y,z
	Return x
End Function
Function VertexY#(surface:TSurface, index)
	Local x#,y#,z#
	surface.GetCoords index,x,y,z
	Return y
End Function
Function VertexZ#(surface:TSurface, index)
	Local x#,y#,z#
	surface.GetCoords index,x,y,z
	Return z
End Function
Function VertexNX#(surface:TSurface, index)
	Local nx#,ny#,nz#
	surface.GetNormal index,nx,ny,nz
	Return nx
End Function
Function VertexNY#(surface:TSurface, index)
	Local nx#,ny#,nz#
	surface.GetNormal index,nx,ny,nz
	Return ny
End Function
Function VertexNZ#(surface:TSurface, index)
	Local nx#,ny#,nz#
	surface.GetNormal index,nx,ny,nz
	Return nz
End Function
Function VertexRed(surface:TSurface, index)
	Local red,green,blue,alpha#
	surface.GetColor index,red,green,blue,alpha
	Return red
End Function
Function VertexGreen(surface:TSurface, index)
	Local red,green,blue,alpha#
	surface.GetColor index,red,green,blue,alpha
	Return green
End Function
Function VertexBlue(surface:TSurface, index)
	Local red,green,blue,alpha#
	surface.GetColor index,red,green,blue,alpha
	Return blue
End Function
Function VertexAlpha#(surface:TSurface, index)
	Local red,green,blue,alpha#
	surface.GetColor index,red,green,blue,alpha
	Return alpha
End Function
Function VertexU(surface:TSurface, index, set = 0)
	Local u#,v#
	surface.GetTexCoords index,u,v,set
	Return u
End Function
Function VertexV(surface:TSurface, index, set = 0)
	Local u#,v#
	surface.GetTexCoords index,u,v,set
	Return v
End Function
Function VertexW(surface:TSurface, index)
	Throw "Support for 3d tex coords not implemented!"
End Function
Function TriangleVertex(surface:TSurface, index, corner)
	Return surface._triangle[index*3+corner]
End Function

Rem

' CreateCamera
' CameraProjMode
' CameraFogMode
' CameraFogRange
' CameraFogColor
' CameraViewport
' CameraClsMode
' CameraClsColor
' CameraRange
' CameraZoom
' CameraPick
' PickedX
' PickedY
' PickedZ
' PickedNX
' PickedNY
' PickedNZ
' PickedTime
' PickedEntity
' PickedSurface
' PickedTriangle
' CameraProject
' ProjectedX
' ProjectedY
' ProjectedZ
' EntityInView

End Rem

Function CreateLight:TLight(typ=LIGHT_DIRECTIONAL,parent:TEntity=Null)
	Return _currentworld.AddLight(typ,parent)
End Function
Function LightRange(light:TLight,range#)
	Return light.SetRange(range)
End Function
Function LightColor(light:TLight,red,green,blue)
	Return light.SetColor(red,green,blue)
End Function
Function LightConeAngles(light:TLight,inner#,outer#)
	Return light.SetAngles(inner,outer)
End Function

Function CreatePivot:TPivot(parent:TEntity=Null)
	Return _currentworld.AddPivot(parent)
End Function

Rem
' CreateSprite
' LoadSprite
' RotateSprite
' ScaleSprite
' HandleSprite
' SpriteViewMode

' LoadMD2
' AnimateMD2
' MD2AnimTime
' MD2AnimLength
' MD2Animating

' LoadBSP
' BSPAmbientLight
' BSPLighting

' CreatePlane

' CreateMirror

' CreateTerrain
' LoadTerrain
' TerrainSize
' TerrainDetail
' TerrainShading
' TerrainHeight
' ModifyTerrain
' TerrainX
' TerrainY
' TerrainZ

' CreateListener
' Load3DSound
' EmitSound

' ScaleEntity
' PositionEntity
' MoveEntity
' TranslateEntity
' RotateEntity
' TurnEntity
' PointEntity
' AlignToVector

' LoadAnimSeq
' SetAnimKey
' AddAnimSeq
' ExtractAnimSeq
' Animate
' SetAnimTime
' AnimSeq
' AnimLength
' AnimTime
' Animating
End Rem

Function FreeEntity(entity:TEntity)
	Return entity.Free()
End Function
Function CopyEntity:TEntity(entity:TEntity, parent:TEntity = Null)
	Return entity.Copy(parent)
End Function
Function EntityColor(entity:TEntity, red, green, blue)
	Return entity.SetColor(red, green, blue)
End Function
Function EntityAlpha(entity:TEntity, alpha#)
	Return entity.SetAlpha(alpha)
End Function
Function EntityShininess(entity:TEntity, shine#)
	Return entity.SetShine(shine)
End Function
Function EntityTexture(entity:TEntity, texture:TTexture, frame = 0, index = 0)
	Return entity.SetTexture(texture, frame, index)
End Function
Function EntityBlend(entity:TEntity, blend)
	Return entity.SetBlend(blend)
End Function
Function EntityFX(entity:TEntity, fx)
	Return entity.SetFX(fx)
End Function
' EntityAutoFade
Function PaintEntity(entity:TEntity, brush:TBrush)
	Return entity.SetBrush(brush)
End Function
Function EntityOrder(entity:TEntity, order)
	Return entity.SetOrder(order)
End Function
Function HideEntity(entity:TEntity)
	Return entity.SetVisible(False)
End Function
Function ShowEntity(entity:TEntity)
	Return entity.SetVisible(True)
End Function
Function NameEntity(entity:TEntity, name$)
	Return entity.SetName(name)
End Function
Function EntityParent(entity:TEntity, parent:TEntity, glob = True)
	Return entity.SetParent(parent, glob)
End Function
Function GetParent:TEntity(entity:TEntity)
	Return entity.GetParent()
End Function

Function EntityX#(entity:TEntity, glob = False)
	Local x#,y#,z#
	entity.GetPosition x,y,z,glob
	Return x
End Function
Function EntityY#(entity:TEntity, glob = False)
	Local x#,y#,z#
	entity.GetPosition x,y,z,glob
	Return y
End Function
Function EntityZ#(entity:TEntity, glob = False)
	Local x#,y#,z#
	entity.GetPosition x,y,z,glob
	Return z
End Function
' EntityRoll
' EntityYaw
' EntityPitch
' EntityClass
' EntityName
' CountChildren
' GetChild
' FindChild
' EntityPick
' LinePick
' EntityVisible
' EntityDistance
' DeltaYaw
' DeltaPitch

Function TFormPoint(x#,y#,z#,src:TEntity,dest:TEntity)
	Local matrix:TMatrix = src.GetMatrix()
	matrix.TransformVec3 x,y,z
	tform_x = x
	tform_y = y
	tform_z = z
End Function
' TFormVector
' TFormNormal
Function TFormedX#()
	Return tform_x
End Function
Function TFormedY#()
	Return tform_y
End Function
Function TFormedZ#()
	Return tform_z
End Function

' GetMatElement

' ResetEntity
' EntityRadius
' EntityBox
' EntityType
' EntityPickMode
' EntityCollided
' CountCollisions
' CollisionX
' CollisionY
' CollisionZ
' CollisionNX
' CollisionNY
' CollisionNZ
' CollisionTime
' CollisionEntity
' CollisionSurface
' CollisionTriangle
Function GetEntityType(entity:TEntity)
	Return entity.GetType()
End Function

' VectorYaw
' VectorPitch

' CountGfxModes3D
' GfxMode3D
' GfxMode3DExists
' GfxDriver3D
' GfxDriverCaps3D
' Windowed3D
' HWTexUnits

Function ClsColor(red,green,blue)
	Return SetClsColor(red,green,blue)
End Function

SetWorld CreateWorld()

Strict

Rem
	bbdoc: Blitz3D style wrapper for MaxB3D
End Rem
Module MaxB3D.Retro
ModuleInfo "Author: Kevin Primm"
ModuleInfo "License: MIT"

Import MaxB3D.GLDriver
Import MaxB3D.D3D9Driver
Import MaxB3D.Primitives

Import MaxB3D.B3DCollision

Import MaxB3D.A3DSLoader
Import MaxB3D.B3DLoader
Import MaxB3D.MD2Loader
Import MaxB3D.XLoader

Import BRL.BMPLoader
Import BRL.JPGLoader
Import BRL.PNGLoader
Import BRL.TGALoader

Private
Global _currentworld:TWorld
Global _renderinfo:TRenderInfo = New TRenderInfo

Public

Function Graphics3D(width, height, depth = 32, mode = 0)
	Select mode
	Case 0
?Debug
		depth = 0
?Not Debug
		depth = 32
?
	Case 1
		depth = 32
	Case 2
		depth = 0
	End Select
	Graphics width,height,depth
End Function
Rem
# Dither
# WBuffer
# AntiAlias
End Rem
Function Wireframe(enable)
	_currentworld.SetWireFrame enable
End Function
'# HWMultiTex
Function AmbientLight(red, green, blue)
	_currentworld.SetAmbientLight red, green, blue
End Function
Rem
# ClearCollisions
# Collisions
End Rem
Function UpdateWorld(speed# = 1.0)
	_currentworld.Update(speed)
End Function
Function RenderWorld(tween# = 1.0)
	_renderinfo = _currentworld.Render(tween)
End Function
Rem
# CaptureWorld
# ClearWorld
# LoaderMatrix
End Rem
Function TrisRendered()
	Return _renderinfo.triangles
End Function

Rem
# CreateTexture
# LoadTexture
# LoadAnimTexture
# FreeTexture
# TextureBlend
# TextureCoords
# ScaleTexture
# PositionTexture
# RotateTexture
End Rem
Function TextureWidth(texture:TTexture)
	Local width,height
	texture.GetSize width,height
	Return width
End Function
Function TextureHeight(texture:TTexture)
	Local width,height
	texture.GetSize width,height
	Return height
End Function
Rem
# TextureName
# GetBrushTexture
End Rem
Function ClearTextureFilters()
	Return _currentworld.ClearTextureFilters()
End Function
Function TextureFilter(text$, flags)
	Return _currentworld.AddTextureFilter(text, flags)
End Function
Rem
# SetCubeFace
# SetCubeMode
End Rem

Function CreateBrush:TBrush(red=255,green=255,blue=255)
	Return _currentworld.AddBrush([red,green,blue])
End Function
Function CopyBrush:TBrush(brush:TBrush)
	Return brush.Copy()
End Function
Function BrushColor(brush:TBrush,red,green,blue)
	Return brush.SetColor(red,green,blue)
End Function
Function BrushAlpha(brush:TBrush,alpha#)
	Return brush.SetAlpha(alpha)
End Function
Function BrushShininess(brush:TBrush,shine#)
	Return brush.SetShine(shine)
End Function
Function BrushTexture(brush:TBrush,texture:TTexture,index=0,frame=0)
	Return brush.SetTexture(texture,index,frame)
End Function
Function BrushFX(brush:TBrush,fx)
	Return brush.SetFX(fx)
End Function
Function BrushBlend(brush:TBrush,fx)
	Return brush.SetBlend(fx)
End Function

Rem
# LoadBrush
# FreeBrush
# GetEntityBrush
# GetSurfaceBrush

# CreateMesh
# LoadMesh
# LoadAnimMesh
# CreateCube
# CreateSphere
# CreateCylinder
# CreateCone
# CopyMesh
# AddMesh
# FlipMesh
# PaintMesh
# LightMesh
# FitMesh
# ScaleMesh
# RotateMesh
# PositionMesh
# UpdateNormals
# MeshesIntersect
# MeshWidth
# MeshHeight
# MeshDepth
# CountSurfaces
# GetSurface

# CreateSurface
# PaintSurface
# ClearSurface
# FindSurface
# AddVertex
# AddTriangle
# VertexCoords
# VertexNormal
# VertexColor
# VertexTexCoords
# CountVertices
# CountTriangles
# VertexX
# VertexY
# VertexZ
# VertexNX
# VertexNY
# VertexNZ
# VertexRed
# VertexGreen
# VertexBlue
# VertexAlpha
# VertexU
# VertexV
# VertexW
# TriangleVertex

# CreateCamera
# CameraProjMode
# CameraFogMode
# CameraFogRange
# CameraFogColor
# CameraViewport
# CameraClsMode
# CameraClsColor
# CameraRange
# CameraZoom
# CameraPick
# PickedX
# PickedY
# PickedZ
# PickedNX
# PickedNY
# PickedNZ
# PickedTime
# PickedEntity
# PickedSurface
# PickedTriangle
# CameraProject
# ProjectedX
# ProjectedY
# ProjectedZ
# EntityInView

End Rem

Function CreateLight:TLight(typ=LIGHT_DIRECTIONAL,parent:TEntity=Null)
	Return _currentworld.AddLight(typ,parent)
End Function
Function LightRange(light:TLight,range#)
	Return light.SetRange(range)
End Function
Function LightColor(light:TLight,red,green,blue)
	Return light.SetColor(red,green,blue)
End Function
Function LightConeAngles(light:TLight,inner#,outer#)
	Return light.SetAngles(inner,outer)
End Function

Function CreatePivot:TPivot(parent:TEntity=Null)
	Return _currentworld.AddPivot(parent)
End Function

Rem
# CreateSprite
# LoadSprite
# RotateSprite
# ScaleSprite
# HandleSprite
# SpriteViewMode

# LoadMD2
# AnimateMD2
# MD2AnimTime
# MD2AnimLength
# MD2Animating

# LoadBSP
# BSPAmbientLight
# BSPLighting

# CreatePlane

# CreateMirror

# CreateTerrain
# LoadTerrain
# TerrainSize
# TerrainDetail
# TerrainShading
# TerrainHeight
# ModifyTerrain
# TerrainX
# TerrainY
# TerrainZ

# CreateListener
# Load3DSound
# EmitSound

# ScaleEntity
# PositionEntity
# MoveEntity
# TranslateEntity
# RotateEntity
# TurnEntity
# PointEntity
# AlignToVector

# LoadAnimSeq
# SetAnimKey
# AddAnimSeq
# ExtractAnimSeq
# Animate
# SetAnimTime
# AnimSeq
# AnimLength
# AnimTime
# Animating
End Rem

Function FreeEntity(entity:TEntity)
	Return entity.Free()
End Function
Function CopyEntity:TEntity(entity:TEntity, parent:TEntity = Null)
	Return entity.Copy(parent)
End Function
Function EntityColor(entity:TEntity, red, green, blue)
	Return entity.SetColor(red, green, blue)
End Function
Function EntityAlpha(entity:TEntity, alpha#)
	Return entity.SetAlpha(alpha)
End Function
Function EntityShininess(entity:TEntity, shine#)
	Return entity.SetShine(shine)
End Function
Function EntityTexture(entity:TEntity, texture:TTexture, frame = 0, index = 0)
	Return entity.SetTexture(texture, frame, index)
End Function
Function EntityBlend(entity:TEntity, blend)
	Return entity.SetBlend(blend)
End Function
Function EntityFX(entity:TEntity, fx)
	Return entity.SetFX(fx)
End Function
'# EntityAutoFade
Function PaintEntity(entity:TEntity, brush:TBrush)
	Return entity.SetBrush(brush)
End Function
Function EntityOrder(entity:TEntity, order)
	Return entity.SetOrder(order)
End Function
Function HideEntity(entity:TEntity)
	Return entity.SetVisible(False)
End Function
Function ShowEntity(entity:TEntity)
	Return entity.SetVisible(True)
End Function
Function NameEntity(entity:TEntity, name$)
	Return entity.SetName(name)
End Function
Function EntityParent(entity:TEntity, parent:TEntity, glob = True)
	Return entity.SetParent(parent, glob)
End Function
Function GetParent:TEntity(entity:TEntity)
	Return entity.GetParent()
End Function

Function EntityX#(entity:TEntity, glob = False)
	Local x#,y#,z#
	entity.GetPosition x,y,z,glob
	Return x
End Function
Function EntityY#(entity:TEntity, glob = False)
	Local x#,y#,z#
	entity.GetPosition x,y,z,glob
	Return y
End Function
Function EntityZ#(entity:TEntity, glob = False)
	Local x#,y#,z#
	entity.GetPosition x,y,z,glob
	Return z
End Function
Rem
# EntityRoll
# EntityYaw
# EntityPitch
# EntityClass
# EntityName
# CountChildren
# GetChild
# FindChild
# EntityPick
# LinePick
# EntityVisible
# EntityDistance
# DeltaYaw
# DeltaPitch
# TFormPoint
# TFormVector
# TFormNormal
# TFormedX
# TFormedY
# TFormedZ
# GetMatElement

# ResetEntity
# EntityRadius
# EntityBox
# EntityType
# EntityPickMode
# EntityCollided
# CountCollisions
# CollisionX
# CollisionY
# CollisionZ
# CollisionNX
# CollisionNY
# CollisionNZ
# CollisionTime
# CollisionEntity
# CollisionSurface
# CollisionTriangle
End Rem
Function GetEntityType(entity:TEntity)
	Return entity.GetType()
End Function

Rem
# VectorYaw
# VectorPitch

# CountGfxModes3D
# GfxMode3D
# GfxMode3DExists
# GfxDriver3D
# GfxDriverCaps3D
# Windowed3D
# HWTexUnits
End Rem

SetWorld CreateWorld()


Added TTexture.Free

Added TTexture.Free

Strict

Import MaxB3D.Logging
Import BRL.Pixmap
Import "worldconfig.bmx"
Import "resource.bmx"

Private
Function ModuleLog(message$)
	TMaxB3DLogger.Write "core/texture",message
End Function

Public

Const TEXTURE_COLOR		= 1
Const TEXTURE_ALPHA		= 2
Const TEXTURE_MASKED	= 4
Const TEXTURE_MIPMAP	= 8
Const TEXTURE_CLAMPU	= 16
Const TEXTURE_CLAMPV	= 32
Const TEXTURE_SPHEREMAP	= 64
Const TEXTURE_CUBEMAP	= 128
Const TEXTURE_VRAM		= 256
Const TEXTURE_HIGHCOLOR	= 512
Const TEXTURE_DEPTH 	= 1024

Const TEXTURE_DEFAULT	= TEXTURE_COLOR
Const TEXTURE_CLAMPUV	= TEXTURE_CLAMPU|TEXTURE_CLAMPV

Const BLEND_NONE      = 0
Const BLEND_ALPHA	     = 1
Const BLEND_MULTIPLY  = 2
Const BLEND_ADD       = 3
Const BLEND_DOT3      = 4
Const BLEND_MULTIPLY2 = 5

Const CUBETEX_LEFT  = 0
Const CUBETEX_FRONT = 1
Const CUBETEX_RIGHT = 2
Const CUBETEX_BACK  = 3
Const CUBETEX_UP    = 4
Const CUBETEX_DOWN  = 5

Type TTexture
	Field _blend=BLEND_MULTIPLY,_coords,_flags
	Field _px#,_py#,_r#,_sx#=1.0,_sy#=1.0
	Field _width=-1,_height=-1,_frame:TTextureFrame[]
	Field _name$

	Field _linklist:TList = New TList

	Method Free()
		For Local link:TLink = EachIn _linklist
			RemoveLink link
		Next
	End Method

	Method Init:TTexture(config:TWorldConfig,url:Object,flags)
		Local pixmap:TPixmap[]

		If Int[](url)
			Local arr[]=Int[](url),width,height,frames=1
			If arr.length=0 Return Null
			If arr.length=1 width=arr[0];height=arr[0]
			If arr.length>1 width=arr[0];height=arr[1]
			If arr.length>2 frames=arr[2]
			pixmap=New TPixmap[frames]
			For Local i=0 To frames-1
				pixmap[i]=CreatePixmap(width,height,PF_BGRA8888)
			Next
		ElseIf TPixmap(url)
			pixmap=[TPixmap(url)]
			If pixmap[0]=Null
				If url ModuleLog "Invalid texture url passed. ("+url.ToString()+")" Else ModuleLog "Invalid texture url passed."
				Return Null
			EndIf
		Else
			pixmap=[LoadPixmap(config.GetStream(url))]
			If pixmap[0]=Null
				If url ModuleLog "Invalid texture url passed. ("+url.ToString()+")" Else ModuleLog "Invalid texture url passed."
				Return Null
			EndIf
		EndIf

		If pixmap.length=0
			If url ModuleLog "Invalid texture url passed. ("+url.ToString()+")" Else ModuleLog "Invalid texture url passed."
			Return Null
		EndIf

		If String(url) flags = config.ProcessTextureFilters(String(url),flags)

		SetName url.ToString()
		SetSize -1,-1,pixmap.length
		For Local i=0 To pixmap.length-1
			If flags&TEXTURE_MASKED pixmap[i] = MaskPixmap(pixmap[i],0,0,0)
			SetPixmap pixmap[i],i
		Next
		SetFlags flags
		config.AddObject Self,WORLDLIST_TEXTURE

		Return Self
	End Method

	Method Lock:TPixmap(index=0)
		_frame[index]._locked=True
		Return _frame[index]._pixmap
	End Method

	Method Unlock(index=0)
		_frame[index]._locked=False
		_frame[index]._updateres=True
	End Method

	Method SetPixmap(pixmap:TPixmap,index=0)
		If pixmap=Null _frame[index]=Null;Return
		If _frame[index]=Null _frame[index]=New TTextureFrame
		_frame[index]._pixmap=ConvertPixmap(pixmap,PF_BGRA8888)
		_frame[index]._updateres=True

		If (_width<>-1 Or _height<>-1) And (_width<>PixmapWidth(pixmap) Or _height<>PixmapHeight(pixmap))
			Throw "Pixmap size does not match texture size."
		Else
			_width=PixmapWidth(pixmap)
			_height=PixmapHeight(pixmap)
		EndIf
	End Method

	Method GetFlags()
		Return _flags
	End Method
	Method SetFlags(flags)
		_flags=flags
	End Method

	Method GetBlend()
		Return _blend
	End Method
	Method SetBlend(blend)
		_blend=blend
	End Method

	Method GetCoords()
		Return _coords
	End Method
	Method SetCoords(set)
		_coords=set
	End Method

	Method GetScale(x# Var,y# Var)
		x=1.0/_sx;y=1.0/_sy
	End Method
	Method SetScale(x#,y#)
		_sx=1.0/x;_sy=1.0/y
	End Method

	Method GetPosition(x# Var,y# Var)
		x=_px;y=_py
	End Method
	Method SetPosition(x#,y#)
		_px=x;_py=y
	End Method

	Method GetRotation#()
		Return _r
	End Method
	Method SetRotation(angle#)
		_r=angle
	End Method

	Method GetSize(width Var,height Var)
		width=_width;height=_height
	End Method
	Method SetSize(width,height,frames)
		_width=width
		_height=height
		_frame=_frame[..frames]
	End Method

	Method GetName$()
		Return _name
	End Method
	Method SetName(name$)
		_name=name
	End Method
End Type

Type TTextureFrame
	Field _res:TTextureRes,_updateres
	Field _pixmap:TPixmap,_locked
	Field _buffer:Object
End Type

Type TTextureRes Extends TDriverResource

End Type

Strict

Import MaxB3D.Logging
Import BRL.Pixmap
Import "worldconfig.bmx"
Import "resource.bmx"

Private
Function ModuleLog(message$)
	TMaxB3DLogger.Write "core/texture",message
End Function

Public

Const TEXTURE_COLOR		= 1
Const TEXTURE_ALPHA		= 2
Const TEXTURE_MASKED	= 4
Const TEXTURE_MIPMAP	= 8
Const TEXTURE_CLAMPU	= 16
Const TEXTURE_CLAMPV	= 32
Const TEXTURE_SPHEREMAP	= 64
Const TEXTURE_CUBEMAP	= 128
Const TEXTURE_VRAM		= 256
Const TEXTURE_HIGHCOLOR	= 512
Const TEXTURE_DEPTH 	= 1024

Const TEXTURE_DEFAULT	= TEXTURE_COLOR
Const TEXTURE_CLAMPUV	= TEXTURE_CLAMPU|TEXTURE_CLAMPV

Const BLEND_NONE      = 0
Const BLEND_ALPHA	     = 1
Const BLEND_MULTIPLY  = 2
Const BLEND_ADD       = 3
Const BLEND_DOT3      = 4
Const BLEND_MULTIPLY2 = 5

Const CUBETEX_LEFT  = 0
Const CUBETEX_FRONT = 1
Const CUBETEX_RIGHT = 2
Const CUBETEX_BACK  = 3
Const CUBETEX_UP    = 4
Const CUBETEX_DOWN  = 5

Type TTexture
	Field _blend=BLEND_MULTIPLY,_coords,_flags
	Field _px#,_py#,_r#,_sx#=1.0,_sy#=1.0
	Field _width=-1,_height=-1,_frame:TTextureFrame[]
	Field _name$

	Method Init:TTexture(config:TWorldConfig,url:Object,flags)
		Local pixmap:TPixmap[]

		If Int[](url)
			Local arr[]=Int[](url),width,height,frames=1
			If arr.length=0 Return Null
			If arr.length=1 width=arr[0];height=arr[0]
			If arr.length>1 width=arr[0];height=arr[1]
			If arr.length>2 frames=arr[2]
			pixmap=New TPixmap[frames]
			For Local i=0 To frames-1
				pixmap[i]=CreatePixmap(width,height,PF_BGRA8888)
			Next
		ElseIf TPixmap(url)
			pixmap=[TPixmap(url)]
			If pixmap[0]=Null
				If url ModuleLog "Invalid texture url passed. ("+url.ToString()+")" Else ModuleLog "Invalid texture url passed."
				Return Null
			EndIf
		Else
			pixmap=[LoadPixmap(config.GetStream(url))]
			If pixmap[0]=Null
				If url ModuleLog "Invalid texture url passed. ("+url.ToString()+")" Else ModuleLog "Invalid texture url passed."
				Return Null
			EndIf
		EndIf

		If pixmap.length=0
			If url ModuleLog "Invalid texture url passed. ("+url.ToString()+")" Else ModuleLog "Invalid texture url passed."
			Return Null
		EndIf

		If String(url) flags = config.ProcessTextureFilters(String(url),flags)

		SetName url.ToString()
		SetSize -1,-1,pixmap.length
		For Local i=0 To pixmap.length-1
			If flags&TEXTURE_MASKED pixmap[i] = MaskPixmap(pixmap[i],0,0,0)
			SetPixmap pixmap[i],i
		Next
		SetFlags flags
		config.AddObject Self,WORLDLIST_TEXTURE

		Return Self
	End Method

	Method Lock:TPixmap(index=0)
		_frame[index]._locked=True
		Return _frame[index]._pixmap
	End Method

	Method Unlock(index=0)
		_frame[index]._locked=False
		_frame[index]._updateres=True
	End Method

	Method SetPixmap(pixmap:TPixmap,index=0)
		If pixmap=Null _frame[index]=Null;Return
		If _frame[index]=Null _frame[index]=New TTextureFrame
		_frame[index]._pixmap=ConvertPixmap(pixmap,PF_BGRA8888)
		_frame[index]._updateres=True

		If (_width<>-1 Or _height<>-1) And (_width<>PixmapWidth(pixmap) Or _height<>PixmapHeight(pixmap))
			Throw "Pixmap size does not match texture size."
		Else
			_width=PixmapWidth(pixmap)
			_height=PixmapHeight(pixmap)
		EndIf
	End Method

	Method GetFlags()
		Return _flags
	End Method
	Method SetFlags(flags)
		_flags=flags
	End Method

	Method GetBlend()
		Return _blend
	End Method
	Method SetBlend(blend)
		_blend=blend
	End Method

	Method GetCoords()
		Return _coords
	End Method
	Method SetCoords(set)
		_coords=set
	End Method

	Method GetScale(x# Var,y# Var)
		x=1.0/_sx;y=1.0/_sy
	End Method
	Method SetScale(x#,y#)
		_sx=1.0/x;_sy=1.0/y
	End Method

	Method GetPosition(x# Var,y# Var)
		x=_px;y=_py
	End Method
	Method SetPosition(x#,y#)
		_px=x;_py=y
	End Method

	Method GetRotation#()
		Return _r
	End Method
	Method SetRotation(angle#)
		_r=angle
	End Method

	Method GetSize(width Var,height Var)
		width=_width;height=_height
	End Method
	Method SetSize(width,height,frames)
		_width=width
		_height=height
		_frame=_frame[..frames]
	End Method

	Method GetName$()
		Return _name
	End Method
	Method SetName(name$)
		_name=name
	End Method
End Type

Type TTextureFrame
	Field _res:TTextureRes,_updateres
	Field _pixmap:TPixmap,_locked
	Field _buffer:Object
End Type

Type TTextureRes Extends TDriverResource

End Type


method.bmx: * Added line breaks to the end of the method implementation and removed them from the concatenation operations.

Strict

Import "metadata.bmx"

Private

Const METH_PREFIX$="_lugi_glue"	' An _ will always follow this

Public

Type LExposedMethod
	Field methodid:TMethod
	Field owner:TTypeId
	Field name$
	Field hidden%
	Field tag$

	Method New()
		Const TAGCHARS$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"

		' generate a short tag to follow the method name, just to reduce the chance of conflicts
		Local tagbuff:Short[7]
		tagbuff[0] = 95 ' underscore
		For Local i:Int = 1 Until tagbuff.Length
			tagbuff[i] = TAGCHARS[Rand(0,62)]
		Next
		tag = String.FromShorts(tagbuff, tagbuff.Length)
	End Method

	Method InitWithMethod:LExposedMethod(meth:TMethod, owner:TTypeId)
		methodid = meth
		Self.owner = owner

		' get metadata
		hidden = methodid.Metadata(LUGI_META_HIDDEN).ToInt()>0

		name = methodid.Metadata(LUGI_META_RENAME).Trim()
		If Not name Then
			name = methodid.Name()
		EndIf

		Return Self
	End Method

	Method PreInitBlock:String()
	End Method

	Method PostInitBlock:String()
	End Method

	Method ImplementationName$()
		Return METH_PREFIX+"_"+owner.Name()+"_"+name+tag
	End Method

	Method Implementation:String( instanceMethod:Int )
		If hidden Then
			Return Null
		EndIf

		Local head$ = "Function "+ImplementationName()+"(lua_vm:Byte Ptr)~n"
		Local tail$ = "End Function~n"

		If instanceMethod Then
			Return head+__instanceImp()+tail
		Else
			Return head+__noclassImp()+tail
		EndIf
	End Method

	' Implementation for instances/static types
	Method __instanceImp:String()
	End Method

	' Implementation for types without classes
	Method __noclassImp:String()

	End Method
End Type

Strict

Import "metadata.bmx"

Private

Const METH_PREFIX$="_lugi_glue"	' An _ will always follow this

Public

Type LExposedMethod
	Field methodid:TMethod
	Field owner:TTypeId
	Field name$
	Field hidden%
	Field tag$

	Method New()
		Const TAGCHARS$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"

		' generate a short tag to follow the method name, just to reduce the chance of conflicts
		Local tagbuff:Short[7]
		tagbuff[0] = 95 ' underscore
		For Local i:Int = 1 Until tagbuff.Length
			tagbuff[i] = TAGCHARS[Rand(0,62)]
		Next
		tag = String.FromShorts(tagbuff, tagbuff.Length)
	End Method

	Method InitWithMethod:LExposedMethod(meth:TMethod, owner:TTypeId)
		methodid = meth
		Self.owner = owner

		' get metadata
		hidden = methodid.Metadata(LUGI_META_HIDDEN).ToInt()>0

		name = methodid.Metadata(LUGI_META_RENAME).Trim()
		If Not name Then
			name = methodid.Name()
		EndIf

		Return Self
	End Method

	Method PreInitBlock:String()
	End Method

	Method PostInitBlock:String()
	End Method

	Method ImplementationName$()
		Return METH_PREFIX+"_"+owner.Name()+"_"+name+tag
	End Method

	Method Implementation:String( instanceMethod:Int )
		If hidden Then
			Return Null
		EndIf

		Local head$ = "Function "+ImplementationName()+"(lua_vm:Byte Ptr)"
		Local tail$ = "End Function"

		If instanceMethod Then
			Return head+"~n"+__instanceImp()+"~n"+tail
		Else
			Return head+"~n"+__noclassImp()+"~n"+tail
		EndIf
	End Method

	' Implementation for instances/static types
	Method __instanceImp:String()
	End Method

	' Implementation for types without classes
	Method __noclassImp:String()

	End Method
End Type


Removed leftover DebugLog

Removed leftover DebugLog

Strict

'Derived from Warner's engine.
'http://code.google.com/p/warner-engine/

Import "entity.bmx"
Import "roamstep4d.c"

Import BRL.Random

Type TTerrain Extends TEntity
	Field _heights#[], _size, _lmax, _max_tris, _clmax#
	Field _handle:Byte Ptr, _data:Float Ptr,_count
	Field _update

	Method New()
			SetDetail 14,12000
	End Method

	Method Free()
		Super.Free

		_heights = Null

		If _handle
			roam_free _handle
			_handle = Null
		EndIf
	End Method

	Method Lists[]()
		Return Super.Lists()+[WORLDLIST_TERRAIN, WORLDLIST_RENDER]
	End Method

	Method CopyData:TEntity(entity:TEntity)
		Local terrain:TTerrain = TTerrain(entity)
		Return Super.CopyData(entity)
	End Method

	Method Copy:TTerrain(parent:TEntity=Null)
		Return TTerrain(Super.Copy_(parent))
	End Method

	Method SetMap(url:Object)
		Local pixmap:TPixmap=TPixmap(url)
		If pixmap=Null pixmap=LoadPixmap(url)
		If pixmap
			_size=Max(PixmapWidth(pixmap),PixmapHeight(pixmap))
			Local s=1
			While s<_size;s:*2;Wend
			_size=s
			_heights=New Float[_size*_size]
			pixmap=ResizePixmap(pixmap,_size,_size)
			For Local i = 0 To _size-1
				For Local j = 0 To _size-1
					SetHeight ((ReadPixel(pixmap, i, j) & $FF)/255.0)*3,j,i
				Next
			Next
		ElseIf Int[](url)
			_size = Int[](url)[0]
			_heights=New Float[_size*_size]
		Else
			_heights=New Float[_size*_size]
		EndIf
		_update=True
	End Method

	Method GetHeight#(x,z)
		Return _heights[(z*_size)+x]
	End Method
	Method SetHeight(height#,x,z)
		_heights[(z*_size)+x]=height
	End Method

	Method GetSize()
		Return _size
	End Method

	Method SetDetail(lmax, max_tris, clmax=-1)
		If clmax = -1 clmax = lmax
		_lmax = Min(lmax,44)
		_max_tris = max_tris
		_clmax = Min(clmax,44)

		If _handle
			roam_set_lmax _handle, lmax
			roam_set_tricntmax _handle, _max_tris

			For Local l = 0 To 44
				roam_set_displacement _handle,l,0.3/Sqr(1 Shl l)
			Next
		EndIf
	End Method

	Method Update(x#,y#,z#,frustrum:Float Ptr)
		If _handle = Null
			_handle=roam_create(_heights, _size)
			SetDetail _lmax,_max_tris,_clmax
		EndIf

		If _update
			roam_set_heightdata _handle, _heights, _size
			roam_update_heightdata _handle
			_update = False
		EndIf

		_matrix.TransformVec3 x,y,z
		roam_set_frustum _handle,x,y,z,frustrum
		roam_optimize _handle
		_data=roam_getdata(_handle, _count)
	End Method
End Type

Extern "C"
	Function roam_create:Byte Ptr(heightdata:Float Ptr, size:Int)
	Function roam_set_frustum( terrain:Byte Ptr, cx#,cy#,cz#, frustum:Float Ptr )
	Function roam_set_lmax( terrain:Byte Ptr, lmax% )
	Function roam_draw( terrain:Byte Ptr )
	Function roam_set_tricntmax( terrain:Byte Ptr, lmax% )
	Function roam_set_iqfine( terrain:Byte Ptr, lmax% )

	Function roam_optimize( terrain:Byte Ptr )
	Function roam_set_heightdata( terrain:Byte Ptr, heightdata:Float Ptr, size% )
	Function roam_update_heightdata( terrain:Byte Ptr )

	Function roam_getdata:Float Ptr( terrain:Byte Ptr, count% Var )
	Function roam_set_displacement( terrain:Byte Ptr, index%, displacement#)

	Function getHeight#( terrain:Byte Ptr, x#,y# )
	Function roam_free( terrain:Byte Ptr )
End Extern

Strict

'Derived from Warner's engine.
'http://code.google.com/p/warner-engine/

Import "entity.bmx"
Import "roamstep4d.c"

Import BRL.Random

Type TTerrain Extends TEntity
	Field _heights#[], _size, _lmax, _max_tris, _clmax#
	Field _handle:Byte Ptr, _data:Float Ptr,_count
	Field _update

	Method New()
			SetDetail 14,12000
	End Method

	Method Free()
		Super.Free

		_heights = Null

		If _handle
			roam_free _handle
			_handle = Null
		EndIf
	End Method

	Method Lists[]()
		Return Super.Lists()+[WORLDLIST_TERRAIN, WORLDLIST_RENDER]
	End Method

	Method CopyData:TEntity(entity:TEntity)
		Local terrain:TTerrain = TTerrain(entity)
		Return Super.CopyData(entity)
	End Method

	Method Copy:TTerrain(parent:TEntity=Null)
		Return TTerrain(Super.Copy_(parent))
	End Method

	Method SetMap(url:Object)
		Local pixmap:TPixmap=TPixmap(url)
		If pixmap=Null pixmap=LoadPixmap(url)
		If pixmap
			_size=Max(PixmapWidth(pixmap),PixmapHeight(pixmap))
			Local s=1
			While s<_size;s:*2;Wend
			_size=s
			_heights=New Float[_size*_size]
			pixmap=ResizePixmap(pixmap,_size,_size)
			For Local i = 0 To _size-1
				For Local j = 0 To _size-1
					SetHeight ((ReadPixel(pixmap, i, j) & $FF)/255.0)*3,j,i
				Next
			Next
		ElseIf Int[](url)
			_size = Int[](url)[0]
			_heights=New Float[_size*_size]
		Else
			_heights=New Float[_size*_size]
		EndIf
		_update=True
	End Method

	Method GetHeight#(x,z)
		Return _heights[(z*_size)+x]
	End Method
	Method SetHeight(height#,x,z)
		_heights[(z*_size)+x]=height
	End Method

	Method GetSize()
		Return _size
	End Method

	Method SetDetail(lmax, max_tris, clmax=-1)
		If clmax = -1 clmax = lmax
		_lmax = Min(lmax,44)
		_max_tris = max_tris
		_clmax = Min(clmax,44)

		If _handle
			roam_set_lmax _handle, lmax
			roam_set_tricntmax _handle, _max_tris

			For Local l = 0 To 44
				roam_set_displacement _handle,l,0.3/Sqr(1 Shl l)
			Next
		EndIf
	End Method

	Method Update(x#,y#,z#,frustrum:Float Ptr)
		DebugLog "lde"
		If _handle = Null
			_handle=roam_create(_heights, _size)
			SetDetail _lmax,_max_tris,_clmax
		EndIf

		If _update
			roam_set_heightdata _handle, _heights, _size
			roam_update_heightdata _handle
			_update = False
		EndIf

		_matrix.TransformVec3 x,y,z
		roam_set_frustum _handle,x,y,z,frustrum
		roam_optimize _handle
		_data=roam_getdata(_handle, _count)
	End Method
End Type

Extern "C"
	Function roam_create:Byte Ptr(heightdata:Float Ptr, size:Int)
	Function roam_set_frustum( terrain:Byte Ptr, cx#,cy#,cz#, frustum:Float Ptr )
	Function roam_set_lmax( terrain:Byte Ptr, lmax% )
	Function roam_draw( terrain:Byte Ptr )
	Function roam_set_tricntmax( terrain:Byte Ptr, lmax% )
	Function roam_set_iqfine( terrain:Byte Ptr, lmax% )

	Function roam_optimize( terrain:Byte Ptr )
	Function roam_set_heightdata( terrain:Byte Ptr, heightdata:Float Ptr, size% )
	Function roam_update_heightdata( terrain:Byte Ptr )

	Function roam_getdata:Float Ptr( terrain:Byte Ptr, count% Var )
	Function roam_set_displacement( terrain:Byte Ptr, index%, displacement#)

	Function getHeight#( terrain:Byte Ptr, x#,y# )
	Function roam_free( terrain:Byte Ptr )
End Extern