فهرست منبع

Entity properties now default to World.

Mark Sibly 8 سال پیش
والد
کامیت
9a28f11c0e

+ 3 - 3
modules/mojo3d/graphics/animator.monkey2

@@ -39,9 +39,9 @@ Class Animator
 			Local channel:=animation.Channels[i]
 			If Not channel continue
 			
-			_entities[i].Position=channel.GetPosition( time )
-			_entities[i].Basis=New Mat3f( channel.GetRotation( time ) )
-			_entities[i].Scale=channel.GetScale( time )
+			_entities[i].LocalPosition=channel.GetPosition( time )
+			_entities[i].LocalBasis=New Mat3f( channel.GetRotation( time ) )
+			_entities[i].LocalScale=channel.GetScale( time )
 		End
 		
 	End

+ 1 - 1
modules/mojo3d/graphics/deferredrenderer.monkey2

@@ -43,7 +43,7 @@ Class DeferredRenderer Extends Renderer
 	
 		_uniforms.SetVec4f( "LightColor",light.Color )
 		_uniforms.SetFloat( "LightRange",light.Range )
-		_uniforms.SetMat4f( "LightViewMatrix",_camera.InverseWorldMatrix * light.WorldMatrix )
+		_uniforms.SetMat4f( "LightViewMatrix",_camera.InverseMatrix * light.Matrix )
 		
 		_uniforms.SetMat4f( "InverseProjectionMatrix",-_camera.ProjectionMatrix )
 		

+ 60 - 60
modules/mojo3d/graphics/entity.monkey2

@@ -151,136 +151,136 @@ Class Entity
 		_animator=animator
 	End
 	
-	'***** Local space properties *****
-
-	#rem monkeydoc Local transformation matrix.
+	'***** World space properties *****
 	
-	The local matrix combines the local position, orientation and scale of the entity into a single affine 4x4 matrix.
+	#rem monkeydoc World space transformation matrix.
+	
+	The world matrix combines the world position, basis matrix and scale of the entity into a single affine 4x4 matrix.
 	
 	#end
 	Property Matrix:AffineMat4f()
 		
-		If _dirty & Dirty.M
-			_M=New AffineMat4f( _r.Scale( _s ),_t )
-			_dirty&=~Dirty.M
+		If _dirty & Dirty.W
+			_W=_parent ? _parent.Matrix * LocalMatrix Else LocalMatrix
+			_dirty&=~Dirty.W
 		Endif
 		
-		Return _M
+		Return _W
 	End
-
-	#rem monkeydoc Local position.
+	
+	#rem monkeydoc Inverse world space transformation matrix.
+	#end
+	Property InverseMatrix:AffineMat4f()
+		
+		If _dirty & Dirty.IW
+			_IW=-Matrix
+			_dirty&=~Dirty.IW
+		Endif
+		
+		Return _IW
+	End
+	
+	#rem monkeydoc World space position.
 	#end
 	Property Position:Vec3f()
-
-		Return _t
+		
+		Return Matrix.t
 		
 	Setter( position:Vec3f )
 		
-		_t=position
+		_t=_parent ? _parent.InverseMatrix * position Else position
 		
 		Invalidate()
 	End
 	
-	#rem monkeydoc Local basis matrix.
-	
-	A basis matrix is a 3x3 matrix representation of an orientation.
+	#rem monkeydoc World space basis matrix.
 
+	A basis matrix is a 3x3 matrix representation of an orientation.
+	
 	A basis matrix is orthogonal (ie: the i,j,k members are perpendicular to each other) and normalized (ie: the i,j,k members all have unit length).
 	
 	#end
 	Property Basis:Mat3f()
 		
-		Return _r
+		Return _parent ? _parent.Basis * _r Else _r
 	
 	Setter( basis:Mat3f )
 		
-		_r=basis
+		_r=_parent ? ~_parent.Basis * basis Else basis
 		
 		Invalidate()
 	End
-
-	#rem monkeydoc Local scale.
+	
+	#rem monkeydoc World space scale.
 	#end	
 	Property Scale:Vec3f()
 		
-		Return _s
+		Return _parent ? _s * _parent.Scale Else _s
 	
 	Setter( scale:Vec3f )
 		
-		_s=scale
+		_s=_parent ? scale / _parent.Scale Else scale
 		
 		Invalidate()
 	End
 	
-	'***** World space properties *****
-	
-	#rem monkeydoc World transformation matrix.
-	
-	The world matrix combines the world position, basis matrix and scale of the entity into a single affine 4x4 matrix.
+	'***** Local space properties *****
+
+	#rem monkeydoc Local space transformation matrix.
 	
-	#end
-	Property WorldMatrix:AffineMat4f()
-		
-		If _dirty & Dirty.W
-			_W=_parent ? _parent.WorldMatrix * Matrix Else Matrix
-			_dirty&=~Dirty.W
-		Endif
-		
-		Return _W
-	End
+	The local matrix combines the local position, orientation and scale of the entity into a single affine 4x4 matrix.
 	
-	#rem monkeydoc Inverse world matrix.
 	#end
-	Property InverseWorldMatrix:AffineMat4f()
+	Property LocalMatrix:AffineMat4f()
 		
-		If _dirty & Dirty.IW
-			_IW=-WorldMatrix
-			_dirty&=~Dirty.IW
+		If _dirty & Dirty.M
+			_M=New AffineMat4f( _r.Scale( _s ),_t )
+			_dirty&=~Dirty.M
 		Endif
 		
-		Return _IW
+		Return _M
 	End
-	
-	#rem monkeydoc World position.
+
+	#rem monkeydoc Local space position.
 	#end
-	Property WorldPosition:Vec3f()
-		
-		Return WorldMatrix.t
+	Property LocalPosition:Vec3f()
+
+		Return _t
 		
 	Setter( position:Vec3f )
 		
-		_t=_parent ? _parent.InverseWorldMatrix * position Else position
+		_t=position
 		
 		Invalidate()
 	End
 	
-	#rem monkeydoc World basis matrix.
-
-	A basis matrix is a 3x3 matrix representation of an orientation.
+	#rem monkeydoc Local space basis matrix.
 	
+	A basis matrix is a 3x3 matrix representation of an orientation.
+
 	A basis matrix is orthogonal (ie: the i,j,k members are perpendicular to each other) and normalized (ie: the i,j,k members all have unit length).
 	
 	#end
-	Property WorldBasis:Mat3f()
+	Property LocalBasis:Mat3f()
 		
-		Return _parent ? _parent.WorldBasis * _r Else _r
+		Return _r
 	
 	Setter( basis:Mat3f )
 		
-		_r=_parent ? ~_parent.WorldBasis * basis Else basis
+		_r=basis
 		
 		Invalidate()
 	End
-	
-	#rem monkeydoc World scale.
+
+	#rem monkeydoc Local space scale.
 	#end	
-	Property WorldScale:Vec3f()
+	Property LocalScale:Vec3f()
 		
-		Return _parent ? Scale * _parent.WorldScale Else _s
+		Return _s
 	
 	Setter( scale:Vec3f )
 		
-		_s=_parent ? scale / _parent.WorldScale Else scale
+		_s=scale
 		
 		Invalidate()
 	End

+ 167 - 170
modules/mojo3d/graphics/entityexts.monkey2

@@ -13,7 +13,7 @@ Public
 #end
 Class Entity Extension
 
-	#rem monkeydoc Local rotation in degrees.
+	#rem monkeydoc Local space rotation in degrees.
 	#end
 	Property Rotation:Vec3f()
 		
@@ -24,18 +24,90 @@ Class Entity Extension
 		Basis=Mat3f.Rotation( rotation * DegreesToRadians )
 	End
 	
-	#rem monkeydoc World rotation in degrees.
+	#rem monkeydoc Local space rotation in degrees.
 	#end
-	Property WorldRotation:Vec3f()
+	Property LocalRotation:Vec3f()
 		
-		Return WorldBasis.GetRotation() * RadiansToDegrees
+		Return LocalBasis.GetRotation() * RadiansToDegrees
 	
 	Setter( rotation:Vec3f )
 		
-		WorldBasis=Mat3f.Rotation( rotation * DegreesToRadians )
+		Basis=Mat3f.Rotation( rotation * DegreesToRadians )
 	End
 	
-	#rem monkeydoc X coordinate of local position.
+	#Rem monkeydoc World space rotation around the X axis in degrees.
+	#End
+	Property Rx:Float()
+		
+		Return Rotation.x
+		
+	Setter( rx:Float )
+		
+		Local r:=Rotation
+		Rotation=New Vec3f( rx,r.y,r.z )
+	End
+
+	#Rem monkeydoc World space rotation around the Y axis in degrees.
+	#End
+	Property Ry:Float()
+		
+		Return Rotation.y
+		
+	Setter( ry:Float )
+		
+		Local r:=Rotation
+		Rotation=New Vec3f( r.x,ry,r.z )
+	End
+
+	#Rem monkeydoc World space rotation around the Z axis in degrees.
+	#End
+	Property Rz:Float()
+		
+		Return Rotation.z
+		
+	Setter( rz:Float )
+		
+		Local r:=Rotation
+		Rotation=New Vec3f( r.x,r.y,rz )
+	End
+	
+	#Rem monkeydoc Local space rotation around the X axis in degrees.
+	#End
+	Property LocalRx:Float()
+		
+		Return LocalRotation.x
+		
+	Setter( rx:Float )
+		
+		Local r:=LocalRotation
+		LocalRotation=New Vec3f( rx,r.y,r.z )
+	End
+
+	#Rem monkeydoc Local space rotation around the Y axis in degrees.
+	#End
+	Property LocalRy:Float()
+		
+		Return LocalRotation.y
+		
+	Setter( ry:Float )
+		
+		Local r:=LocalRotation
+		LocalRotation=New Vec3f( r.x,ry,r.z )
+	End
+
+	#Rem monkeydoc Local space rotation around the Z axis in degrees.
+	#End
+	Property LocalRz:Float()
+		
+		Return LocalRotation.z
+		
+	Setter( rz:Float )
+		
+		Local r:=LocalRotation
+		LocalRotation=New Vec3f( r.x,r.y,rz )
+	End
+
+	#rem monkeydoc World space X coordinate.
 	#end
 	Property X:Float()
 		
@@ -47,7 +119,7 @@ Class Entity Extension
 		Position=New Vec3f( x,v.y,v.z )
 	End
 	
-	#rem monkeydoc Y coordinate of local position.
+	#rem monkeydoc World space Y coordinate.
 	#end
 	Property Y:Float()
 	
@@ -59,7 +131,7 @@ Class Entity Extension
 		Position=New Vec3f( v.x,y,v.z )
 	End
 
-	#rem monkeydoc Z coordinate of local position.
+	#rem monkeydoc World space Z coordinate.
 	#end
 	Property Z:Float()
 	
@@ -71,115 +143,43 @@ Class Entity Extension
 		Position=New Vec3f( v.x,v.y,z )
 	End
 	
-	#rem monkeydoc X coordinate of world position.
+	#rem monkeydoc Local space X coordinate.
 	#end
-	Property WorldX:Float()
+	Property LocalX:Float()
 		
-		Return WorldPosition.x
+		Return LocalPosition.x
 		
 	Setter( x:Float )
 
-		Local v:=WorldPosition		
-		WorldPosition=New Vec3f( x,v.y,v.z )
+		Local v:=LocalPosition		
+		LocalPosition=New Vec3f( x,v.y,v.z )
 	End
 	
-	#rem monkeydoc Y coordinate of world position.
+	#rem monkeydoc Local space Y coordinate.
 	#end
-	Property WorldY:Float()
+	Property LocalY:Float()
 	
-		Return WorldPosition.y
+		Return LocalPosition.y
 	
 	Setter( y:Float )
 		
-		Local v:=WorldPosition		
-		WorldPosition=New Vec3f( v.x,y,v.z )
+		Local v:=LocalPosition		
+		LocalPosition=New Vec3f( v.x,y,v.z )
 	End
 
-	#rem monkeydoc Z coordinate of world position.
+	#rem monkeydoc Local space Z coordinate.
 	#end
-	Property WorldZ:Float()
+	Property LocalZ:Float()
 	
-		Return WorldPosition.z
+		Return LocalPosition.z
 	
 	Setter( z:Float )
 		
-		Local v:=WorldPosition		
-		WorldPosition=New Vec3f( v.x,v.y,z )
-	End
-	
-	#Rem monkeydoc Rotation around the X axis in degrees.
-	#End
-	Property Rx:Float()
-		
-		Return Rotation.x
-		
-	Setter( rx:Float )
-		
-		Local r:=Rotation
-		Rotation=New Vec3f( rx,r.y,r.z )
-	End
-
-	#Rem monkeydoc Rotation around the Y axis in degrees.
-	#End
-	Property Ry:Float()
-		
-		Return Rotation.y
-		
-	Setter( ry:Float )
-		
-		Local r:=Rotation
-		Rotation=New Vec3f( r.x,ry,r.z )
-	End
-
-	#Rem monkeydoc Rotation around the X axis in degrees.
-	#End
-	Property Rz:Float()
-		
-		Return Rotation.z
-		
-	Setter( rz:Float )
-		
-		Local r:=Rotation
-		Rotation=New Vec3f( r.x,r.y,rz )
-	End
-
-	#Rem monkeydoc Rotation around the X axis in degrees.
-	#End
-	Property WorldRx:Float()
-		
-		Return WorldRotation.x
-		
-	Setter( rx:Float )
-		
-		Local r:=WorldRotation
-		WorldRotation=New Vec3f( rx,r.y,r.z )
-	End
-
-	#Rem monkeydoc Rotation around the Y axis in degrees.
-	#End
-	Property WorldRy:Float()
-		
-		Return WorldRotation.y
-		
-	Setter( ry:Float )
-		
-		Local r:=WorldRotation
-		WorldRotation=New Vec3f( r.x,ry,r.z )
-	End
-
-	#Rem monkeydoc Rotation around the X axis in degrees.
-	#End
-	Property WorldRz:Float()
-		
-		Return WorldRotation.z
-		
-	Setter( rz:Float )
-		
-		Local r:=WorldRotation
-		WorldRotation=New Vec3f( r.x,r.y,rz )
+		Local v:=LocalPosition		
+		LocalPosition=New Vec3f( v.x,v.y,z )
 	End
 	
-	#rem monkeydoc Scale on the x axis.
+	#rem monkeydoc World space scale on the X axis.
 	#end
 	Property Sx:Float()
 		
@@ -191,7 +191,7 @@ Class Entity Extension
 		Scale=New Vec3f( sx,s.y,s.z )
 	End
 	
-	#rem monkeydoc Scale on the y axis.
+	#rem monkeydoc World space scale on the Y axis.
 	#end
 	Property Sy:Float()
 		
@@ -203,7 +203,7 @@ Class Entity Extension
 		Scale=New Vec3f( s.x,sy,s.z )
 	End
 	
-	#rem monkeydoc Scale on the z axis.
+	#rem monkeydoc World space scale on the Z axis.
 	#end
 	Property Sz:Float()
 		
@@ -212,123 +212,120 @@ Class Entity Extension
 	Setter( sz:Float )
 		
 		Local s:=Scale
-		
 		Scale=New Vec3f( s.x,s.y,sz )
 	End
 	
-	#rem monkeydoc Scale on the x axis.
+	#rem monkeydoc Local space scale on the X axis.
 	#end
-	Property WorldSx:Float()
+	Property LocalSx:Float()
 		
-		Return WorldScale.x
+		Return LocalScale.x
 	
 	Setter( sx:Float )
 		
-		Local s:=WorldScale
+		Local s:=LocalScale
 		
-		WorldScale=New Vec3f( sx,s.y,s.z )
+		LocalScale=New Vec3f( sx,s.y,s.z )
 	End
 	
-	#rem monkeydoc Scale on the y axis.
+	#rem monkeydoc Local space scale on the Y axis.
 	#end
-	Property WorldSy:Float()
+	Property LocalSy:Float()
 		
-		Return WorldScale.y
+		Return LocalScale.y
 	
 	Setter( sy:Float )
 		
-		Local s:=WorldScale
-		
-		WorldScale=New Vec3f( s.x,sy,s.z )
+		Local s:=LocalScale
+		LocalScale=New Vec3f( s.x,sy,s.z )
 	End
 	
-	#rem monkeydoc Scale on the z axis.
+	#rem monkeydoc Local space scale on the Z axis.
 	#end
-	Property WorldSz:Float()
+	Property LocalSz:Float()
 		
-		Return WorldScale.z
+		Return LocalScale.z
 	
 	Setter( sz:Float )
 		
-		Local s:=WorldScale
-		
-		WorldScale=New Vec3f( s.x,s.y,sz )
+		Local s:=LocalScale
+		LocalScale=New Vec3f( s.x,s.y,sz )
 	End
 	
-	#rem monkeydoc Sets entity basis matrix in local or world space.
+	#rem monkeydoc Sets entity position in local or world space.
 	#end
-	Method SetBasis( basis:Mat3f,worldSpace:Bool=False )
+	Method SetPosition( position:Vec3f,localSpace:Bool=False )
 		
-		If worldSpace WorldBasis=basis Else Basis=basis
+		If localSpace LocalPosition=position Else Position=position
 	End
 	
-	#rem monkeydoc Gets entity basis matrix in local or world space.
-	#end
-	method GetBasis:Mat3f( worldSpace:Bool=False )
+	Method SetPosition( x:Float,y:Float,z:Float,localSpace:Bool=False )
 		
-		Return worldSpace ? WorldBasis Else Basis
-	
+		SetPosition( New Vec3f( x,y,z ),localSpace )
 	End
-
-	#rem monkeydoc Sets entity position in local or world space.
+	
+	#rem monkeydoc Gets entity position in local or world space.
 	#end
-	Method SetPosition( position:Vec3f,worldSpace:Bool=False )
+	Method GetPostition:Vec3f( localSpace:Bool=False )
 		
-		If worldSpace WorldPosition=position Else Position=position
+		Return localSpace ? LocalPosition Else Position
 	End
 	
-	Method SetPosition( x:Float,y:Float,z:Float,worldSpace:Bool=False )
+	#rem monkeydoc Sets entity basis matrix in local or world space.
+	#end
+	Method SetBasis( basis:Mat3f,localSpace:Bool=False )
 		
-		SetPosition( New Vec3f( x,y,z ),worldSpace )
+		If localSpace LocalBasis=basis Else Basis=basis
 	End
 	
-	#rem monkeydoc Gets entity position in local or world space.
+	#rem monkeydoc Gets entity basis matrix in local or world space.
 	#end
-	Method GetPostition:Vec3f( worldSpace:Bool=False )
+	method GetBasis:Mat3f( localSpace:Bool=False )
 		
-		Return worldSpace ? WorldPosition Else Position
-	End
+		Return localSpace ? LocalBasis Else Basis
 	
+	End
+
 	#rem monkeydoc Sets entity rotation in euler angles in local or world space.
 	#end
-	Method SetRotation( rotation:Vec3f,worldSpace:Bool=False )
+	Method SetRotation( rotation:Vec3f,localSpace:Bool=False )
 		
 		Local basis:=Mat3f.Rotation( rotation * DegreesToRadians )
 		
-		If worldSpace WorldBasis=basis Else Basis=basis
+		If localSpace LocalBasis=basis Else Basis=basis
 	End
 	
-	Method SetRotation( rx:Float,ry:Float,rz:Float,worldSpace:Bool=False )
+	Method SetRotation( rx:Float,ry:Float,rz:Float,localSpace:Bool=False )
 		
-		SetRotation( New Vec3f( rx,ry,rz ),worldSpace )
+		SetRotation( New Vec3f( rx,ry,rz ),localSpace )
 	End
 	
 	#rem monkeydoc Gets entity rotation in euler angles in local or world space.
 	#end
-	Method GetRotation:Vec3f( worldSpace:Bool=False )
+	Method GetRotation:Vec3f( localSpace:Bool=False )
 		
-		Local basis:=worldSpace ? WorldBasis Else Basis
+		Local basis:=localSpace ? LocalBasis Else Basis
 		
 		Return basis.GetRotation() * RadiansToDegrees
 	End
 	
 	#rem monkeydoc Sets entity scale in local or world space.
 	#end
-	Method SetScale( scale:Vec3f,worldSpace:Bool=False )
+	Method SetScale( scale:Vec3f,localSpace:Bool=False )
 		
-		If worldSpace WorldScale=scale Else Scale=scale
+		If localSpace LocalScale=scale Else Scale=scale
 	End
 	
-	Method SetScale( sx:Float,sy:Float,sz:Float,worldSpace:Bool=False )
+	Method SetScale( sx:Float,sy:Float,sz:Float,localSpace:Bool=False )
 		
-		SetScale( New Vec3f( sx,sy,sz ),worldSpace )
+		SetScale( New Vec3f( sx,sy,sz ),localSpace )
 	End
 
 	#rem monkeydoc Gets entity scale in local or world space.
 	#end
-	Method GetScale:Vec3f( worldSpace:Bool=False )
+	Method GetScale:Vec3f( localSpace:Bool=False )
 		
-		Return worldSpace ? WorldScale Else Scale
+		Return localSpace ? LocalScale Else Scale
 	End
 	
 	#rem monkeydoc Moves the entity.
@@ -336,9 +333,9 @@ Class Entity Extension
 	Moves the entity relative to its current orientation.
 	
 	#end	
-	Method Move( tv:Vec3f,worldSpace:Bool=False )
+	Method Move( tv:Vec3f,localSpace:Bool=False )
 		
-		If worldSpace WorldPosition+=tv Else Position+=Basis * tv
+		If localSpace LocalPosition+=tv Else Position+=Basis * tv
 	End
 	
 	Method Move( tx:Float,ty:Float,tz:Float )
@@ -351,9 +348,9 @@ Class Entity Extension
 	Moves the entity relative to its current orientation.
 	
 	#end	
-	Method MoveX( tx:Float,worldSpace:Bool=False )
+	Method MoveX( tx:Float,localSpace:Bool=False )
 		
-		If worldSpace WorldX+=tx Else Position+=Basis.i * tx
+		If localSpace LocalX+=tx Else Position+=Basis.i * tx
 	End
 	
 	#rem monkeydoc Moves the entity on the Y axis.
@@ -361,9 +358,9 @@ Class Entity Extension
 	Moves the entity relative to its current orientation.
 	
 	#end	
-	Method MoveY( ty:Float,worldSpace:Bool=False )
+	Method MoveY( ty:Float,localSpace:Bool=False )
 
-		If worldSpace WorldY+=ty Else Position+=Basis.j * ty
+		If localSpace LocalY+=ty Else Position+=Basis.j * ty
 	End
 	
 	#rem monkeydoc Moves the entity on the Z axis.
@@ -371,75 +368,75 @@ Class Entity Extension
 	Moves the entity relative to its current orientation.
 	
 	#end	
-	Method MoveZ( tz:Float,worldSpace:Bool=False )
+	Method MoveZ( tz:Float,localSpace:Bool=False )
 
-		If worldSpace WorldZ+=tz Else Position+=Basis.k * tz
+		If localSpace LocalZ+=tz Else Position+=Basis.k * tz
 	End
 	
 	#rem monkeydoc Rotates the entity.
 	
 	Rotates the entity.
 	
-	If `postRotate` is true, the rotation is applied after the entity's world rotation.
+	If `localSpace` is false, the rotation is applied after the entity's world rotation.
 		
-	If `postRotate` is false, the rotation is applied before the entity's local rotation.
+	If `localSpace` is true, the rotation is applied before the entity's local rotation.
 		
 	#end
-	Method Rotate( rv:Vec3f,postRotate:Bool=False )
+	Method Rotate( rv:Vec3f,localSpace:Bool=False )
 		
 		Local basis:=Mat3f.Rotation( rv * DegreesToRadians )
 		
-		If postRotate WorldBasis=basis*WorldBasis Else Basis*=basis
+		If localSpace LocalBasis*=basis Else Basis=basis*Basis
 	End
 	
-	Method Rotate( rx:Float,ry:Float,rz:Float,postRotate:Bool=False )
+	Method Rotate( rx:Float,ry:Float,rz:Float,localSpace:Bool=False )
 		
-		Rotate( New Vec3f( rx,ry,rz ),postRotate )
+		Rotate( New Vec3f( rx,ry,rz ),localSpace )
 	End
 	
 	#rem monkeydoc Rotates the entity around the X axis.
 	#end
-	Method RotateX( rx:Float,postRotate:Bool=False )
+	Method RotateX( rx:Float,localSpace:Bool=False )
 		
 		Local basis:=Mat3f.Pitch( rx * DegreesToRadians )
 		
-		If postRotate WorldBasis=basis*WorldBasis Else Basis*=basis
+		If localSpace LocalBasis=basis*LocalBasis Else Basis*=basis
 	End
 
 	#rem monkeydoc Rotates the entity around the Y axis.
 	#end
-	Method RotateY( ry:Float,postRotate:Bool=False )
+	Method RotateY( ry:Float,localSpace:Bool=False )
 
 		Local basis:=Mat3f.Yaw( ry * DegreesToRadians )
 		
-		If postRotate WorldBasis=basis*WorldBasis Else Basis*=basis
+		If localSpace LocalBasis=basis*LocalBasis Else Basis*=basis
 	End
 
 	#rem monkeydoc Rotates the entity around the Z axis.
 	#end
-	Method RotateZ( rz:Float,postRotate:Bool=False )
+	Method RotateZ( rz:Float,localSpace:Bool=False )
 
 		Local basis:=Mat3f.Roll( rz * DegreesToRadians )
 		
-		If postRotate WorldBasis=basis*WorldBasis Else Basis*=basis
+		If localSpace LocalBasis=basis*LocalBasis Else Basis*=basis
 	End
 
 	#rem monkeydoc Points the entity at a target.
 	#end
 	Method PointAt( target:Vec3f,up:Vec3f=New Vec3f( 0,1,0 ) )
 		
-		Local k:=(target-WorldPosition).Normalize()
+		Local k:=(target-LocalPosition).Normalize()
 		
 		Local i:=up.Cross( k ).Normalize()
 		
 		Local j:=k.Cross( i )
 		
-		WorldBasis=New Mat3f( i,j,k )
+		LocalBasis=New Mat3f( i,j,k )
 	End
 	
 	Method PointAt( target:Entity,up:Vec3f=New Vec3f( 0,1,0 ) )
 		
-		PointAt( target.WorldPosition )
+		PointAt( target.LocalPosition )
 	End
-
+	
 End

+ 11 - 5
modules/mojo3d/graphics/gltf2loader.monkey2

@@ -225,13 +225,19 @@ Class Gltf2Loader
 					Next
 				Endif
 				
-				If materials And Not mesh.NumVertices mesh.AddMaterials( 1 )				
-				
 				mesh.AddVertices( vertices )
 				
-				mesh.AddTriangles( indices,mesh.NumMaterials-1 )
-				
-				If materials materials.Push( GetMaterial( prim.material ) )
+				If materials
+					
+					mesh.AddTriangles( indices,mesh.NumMaterials )
+
+					materials.Push( GetMaterial( prim.material ) )
+					
+				Else
+					
+					mesh.AddTriangles( indices,0 )
+					
+				Endif
 					
 				Print "Added "+vcount+" vertices, "+icount+" indices."
 				

+ 6 - 3
modules/mojo3d/graphics/mesh.monkey2

@@ -7,7 +7,7 @@ Class Mesh Extends Resource
 	
 	#rem monkeydoc Creates a new mesh.
 	
-	Creates a new empty mesh with 1 logical material.
+	Creates a new empty mesh.
 	
 	Meshes don't actual contain instances of materials. Instead, mesh triangles are added to 'logical' materials which are effectively just integer indices.
 	
@@ -20,7 +20,6 @@ Class Mesh Extends Resource
 		_bounds=Boxf.EmptyBounds
 		_vbuffer=New VertexBuffer( Vertex3fFormat.Instance,0 )
 		_ibuffers=New Stack<IndexBuffer>
-		AddMaterials( 1 )
 	End
 	
 	Method New( mesh:Mesh )
@@ -135,11 +134,15 @@ Class Mesh Extends Resource
 	
 	#rem monkeydoc Adds triangles to the mesh.
 	
-	The `materialid` parameter must be greater than or equal to 0 and less than NumMaterials.
+	The `materialid` parameter must be greater than or equal to 0 and less or equal to [[NumMaterials]].
+	
+	If `materialid` is equal to NumMaterials, a new material is automatically added first.
 	
 	#end
 	Method AddTriangles( indices:UInt Ptr,count:Int,materialid:Int=0 )
 		
+		If materialid=_ibuffers.Length AddMaterials( 1 )
+		
 		Local p:=_ibuffers[materialid].AddIndices( count )
 		
 		libc.memcpy( p,indices,count*4 )

+ 1 - 1
modules/mojo3d/graphics/model.monkey2

@@ -156,7 +156,7 @@ Class Model Extends Entity
 			
 			For Local i:=0 Until _bones.Length
 				Local bone:=_bones[i]
-				_boneMatrices[i]=New Mat4f( bone.entity.WorldMatrix * bone.offset )
+				_boneMatrices[i]=New Mat4f( bone.entity.Matrix * bone.offset )
 			Next
 		End
 		

+ 7 - 7
modules/mojo3d/graphics/renderer.monkey2

@@ -257,8 +257,8 @@ Class Renderer
 	
 		_camera=camera
 		
-		Local envMat:=_camera.WorldMatrix.m
-		Local viewMat:=_camera.InverseWorldMatrix
+		Local envMat:=_camera.Matrix.m
+		Local viewMat:=_camera.InverseMatrix
 		Local projMat:=_camera.ProjectionMatrix
 		Local invProjMat:=-projMat
 			
@@ -314,7 +314,7 @@ Class Renderer
 		_device.DepthFunc=DepthFunc.LessEqual
 		_device.RenderPass=1
 		
-		RenderRenderOps( _renderQueue.OpaqueOps,_camera.InverseWorldMatrix,_camera.ProjectionMatrix )
+		RenderRenderOps( _renderQueue.OpaqueOps,_camera.InverseMatrix,_camera.ProjectionMatrix )
 	End
 	
 	'MX2_RENDERPASS 0
@@ -326,7 +326,7 @@ Class Renderer
 		_device.DepthFunc=DepthFunc.Always
 		_device.RenderPass=0
 
-		RenderRenderOps( _spriteQueue.OpaqueOps,_camera.InverseWorldMatrix,_camera.ProjectionMatrix )
+		RenderRenderOps( _spriteQueue.OpaqueOps,_camera.InverseMatrix,_camera.ProjectionMatrix )
 	End
 	
 	'MX2_RENDERPASS 2
@@ -351,8 +351,8 @@ Class Renderer
 		_device.CullMode=CullMode.Back
 		_device.RenderPass=2
 
-		Local invLightMatrix:=light.InverseWorldMatrix
-		Local viewLight:=invLightMatrix * _camera.WorldMatrix
+		Local invLightMatrix:=light.InverseMatrix
+		Local viewLight:=invLightMatrix * _camera.Matrix
 		
 		For Local i:=0 Until _csmSplits.Length-1
 			
@@ -428,7 +428,7 @@ Class Renderer
 			
 			Local model:=op.instance
 			
-			Local modelMat:= model ? model.WorldMatrix Else New AffineMat4f
+			Local modelMat:= model ? model.Matrix Else New AffineMat4f
 			Local modelViewMat:=viewMatrix * modelMat
 			Local modelViewProjMat:=projMatrix * modelViewMat
 			Local modelViewNormMat:=~-modelViewMat.m

+ 3 - 3
modules/mojo3d/graphics/spritebuffer.monkey2

@@ -38,7 +38,7 @@ Class SpriteBuffer
 		Endif
 		
 		sprites.Sort( Lambda:Int( x:Sprite,y:Sprite )
-			Return camera.WorldPosition.Distance( y.WorldPosition ) <=> camera.WorldPosition.Distance( x.WorldPosition )
+			Return camera.Position.Distance( y.Position ) <=> camera.Position.Distance( x.Position )
 		End )
 		
 		Local cmaterial:=sprites[0].Material
@@ -53,7 +53,7 @@ Class SpriteBuffer
 				i0=i
 			Endif
 			
-			Local r:=camera.WorldBasis
+			Local r:=camera.Basis
 			
 			Select sprite.Mode
 			Case SpriteMode.Upright
@@ -61,7 +61,7 @@ Class SpriteBuffer
 				r.j=New Vec3f( 0,1,0 ) ; r.i=r.j.Cross( r.k ).Normalize()
 			End
 			
-			Local matrix:=New AffineMat4f( r.Scale( sprite.WorldScale ),sprite.WorldPosition )
+			Local matrix:=New AffineMat4f( r.Scale( sprite.Scale ),sprite.Position )
 			
 			Local handle:=sprite.Handle
 			

+ 1 - 0
modules/mojo3d/tests/cubetest.monkey2

@@ -1,3 +1,4 @@
+
 Namespace myapp
 
 #Import "<std>"

+ 3 - 2
modules/mojo3d/tests/ducks.monkey2

@@ -73,7 +73,6 @@ Class MyWindow Extends Window
 		'		
 		Local duck:=Model.Load( "asset::duck.gltf/Duck.gltf" )
 		duck.Mesh.FitVertices( New Boxf( -1,1 ) )
-		duck.Mesh.TransformVertices( Mat4f.Rotation( 0,Pi/2,0 ) )
 		
 		Local root:=duck.Copy()
 		root.Move( 0,10,0 )
@@ -91,6 +90,8 @@ Class MyWindow Extends Window
 				
 				copy.Move( 0,0,6+m*16 )
 				
+				copy.Scale=New Vec3f( 1 )
+				
 				For Local j:=0 Until copy.Materials.Length
 				
 					Local material:=Cast<PbrMaterial>( copy.Materials[j].Copy() )
@@ -121,7 +122,7 @@ Class MyWindow Extends Window
 		
 		For Local duck:=Eachin _ducks
 			
-			duck.Rotate( 0,1,0 )
+			duck.RotateY( 1 )
 		Next
 		
 		util.Fly( _camera,Self )