Browse Source

mojo3d tweaks.

Mark Sibly 7 years ago
parent
commit
31d02a8f18

+ 14 - 0
VERSIONS.TXT

@@ -1,4 +1,15 @@
 
+Made sure Component.OnStart is always called before any other Component.OnBlah method.
+
+Added 'Protected Internal' access to mx2cc. Decls in protected internal sections in classes are visible both to subclasses, or to module they are declared in.
+ 
+Removed Entity.Collided( rigidBody:RigidBody ) and added RigidBody.Collided( rigidBody:RigidBody ), please use this instead. Removed Component.OnCollided.
+
+Component.OnUpdate now executes before physics update. Added Component.OnEndUpdate for post update processing.
+
+Entity.Destroy() and Component.Destroy() now postphpone destruction until update has finished if called during Scene.Update.
+
+
 ***** Monkey-v2018.07 ***** 
 
 Added thread support and std.thread module!
@@ -17,6 +28,7 @@ Added SUPER experimental SwapAsync flag to Window. Causes window to execute swap
 
 Added extern alias symbols to mx2cc, eg: you can now go `Alias DWORD:UInt="unsigned long"` (inside an Extern section) to get proper win32 dwords (and LPDWORDs that don't break c++).
 
+
 ***** Monkey-v2018.06 Mx2cc-v1.1.14 Ted2go-v2.11 *****
 
 Added WeakRef class. Must be constructed with an Object and has a single Target property that returns Null if object has been GC'd.
@@ -39,6 +51,7 @@ Updated android SDK to: Android Studio 3.1.2 ; Android SDK 27 (Oreo 8.1) ; NDK 1
 
 Point/spot light now render bounding quads instead of fullscreen quads.
 
+
 ***** Monkey-v2018.05 Mx2cc-v1.1.13 Ted2go-2.10 *****
 
 Added simple support for .hdr pixmap/texture/image loading (wont work on android).
@@ -77,6 +90,7 @@ Added low budget OpenUrl for emscripten. It just replaces current page with the
 
 Added zlib module and DataBuffer.Compress and DataBuffer.Decompress.
 
+
 ***** Monkey-v2018.04 Mx2cc-v1.1.12 Ted2go-2.10 *****
 
 Added GetPixel and GetPixelARGB to both Image and Canvas classes - canvas version will be slow as hell, eg: 3 secs for 16x16! Image versions still relies on the 'managed pixmap hack', but I should be able to improve on the speed of this for desktop targets.

+ 68 - 7
modules/mojo3d/scene/component.monkey2

@@ -62,8 +62,24 @@ Class Component
 		Return _type
 	End
 	
+	#rem monkeydoc Destroys the entity immediately or when update finishes.
+	
+	If scene is currently being updated, the component will not be destroyed until update finishes.
+		
+	#end
 	Method Destroy()
 		
+		If _state=State.Destroyed Return
+		
+		If _entity.Scene.Updating
+			If _state=State.Destroying Return
+			_state=State.Destroying
+			_entity.Scene.UpdateFinished+=Destroy
+			Return
+		End
+		
+		_state=State.Destroyed
+		
 		OnDestroy()
 		
 		_entity.RemoveComponent( Self )
@@ -73,8 +89,8 @@ Class Component
 		_type=Null
 	End
 	
-Protected
-
+	Protected
+	
 	Method AddInstance()
 		
 		Local scene:=_entity.Scene
@@ -89,8 +105,6 @@ Protected
 		If scene.Editing scene.Jsonifier.AddInstance( Self,New Variant[]( _entity,component ) )
 	End
 	
-Internal
-
 	Method OnCopy:Component( entity:Entity ) Virtual
 
 		RuntimeError( "Don't know how to copy component of type "+Type.Name )
@@ -98,6 +112,9 @@ Internal
 		Return Null
 	End
 	
+	Method OnStart() Virtual
+	End
+	
 	Method OnShow() virtual
 	End
 	
@@ -107,22 +124,66 @@ Internal
 	Method OnBeginUpdate() Virtual
 	End
 	
-	Method OnStart() Virtual
+	Method OnUpdate( elapsed:Float ) Virtual
 	End
 	
-	Method OnUpdate( elapsed:Float ) Virtual
+	Method OnEndUpdate() Virtual
 	End
 	
 	Method OnDestroy() Virtual
 	End
 	
-	Method OnCollide( body:RigidBody ) virtual
+	Internal
+	
+	Method Copy:Component( entity:Entity )
+		Return OnCopy( entity )
+	End
+	
+	Method Start()
+		If _state<>State.Initial Return
+		_state=State.Started
+		OnStart()
+	End
+	
+	Method Show()
+		Start()
+		If _state<>State.Started Return
+		OnShow()
+	End
+	
+	Method Hide()
+		If _state<>State.Started Return
+		OnHide()
+	End
+	
+	Method BeginUpdate()
+		Start()
+		If _state<>State.Started Return
+		OnBeginUpdate()
+	End
+	
+	Method Update( elapsed:Float )
+		If _state<>State.Started Return
+		OnUpdate( elapsed )
+	End
+	
+	Method EndUpdate()
+		If _state<>State.Started Return
+		OnEndUpdate()
 	End
 	
 	Private
 	
+	Enum State
+		Initial=0
+		Started=1
+		Destroyed=2
+		Destroying=3
+	End
+	
 	Field _entity:Entity
 	Field _type:ComponentType
+	Field _state:State=State.Initial
 End
 
 

+ 11 - 7
modules/mojo3d/scene/components/rigidbody.monkey2

@@ -37,6 +37,10 @@ Public
 
 Class RigidBody Extends Component
 	
+	#rem monkeydoc Invoked when this rigid body collides with another rigid body.
+	#end
+	Field Collided:Void( rigidBody:RigidBody )
+	
 	Const Type:=New ComponentType( "RigidBody",-10,ComponentTypeFlags.Singleton )
 	
 	Method New( entity:Entity )
@@ -297,7 +301,7 @@ Class RigidBody Extends Component
 		
 		Return body
 	End
-
+	
 	Method OnBeginUpdate() Override
 		
 		Validate()
@@ -309,7 +313,7 @@ Class RigidBody Extends Component
 		
 	End
 	
-	Method OnUpdate( elapsed:Float ) Override
+	Method OnEndUpdate() Override
 		
 		_seq=Entity.Seq
 	End
@@ -330,11 +334,6 @@ Class RigidBody Extends Component
 		_dirty|=Dirty.Collider
 	End
 	
-	Property World:World()
-		
-		Return Entity.Scene.World
-	End
-	
 	Private
 	
 	Enum Dirty
@@ -356,6 +355,11 @@ Class RigidBody Extends Component
 	Field _rvisible:Bool
 	Field _seq:Int
 	
+	Property World:World()
+		
+		Return Entity.Scene.World
+	End
+	
 	Method ValidateCollider()
 		
 		If (_dirty & (Dirty.Collider|Dirty.Mass))=0 Return

+ 51 - 32
modules/mojo3d/scene/entity.monkey2

@@ -68,7 +68,7 @@ Class Entity Extends DynamicObject Abstract
 		Return copy
 	End
 	
-	#rem monkeydoc Sequence id.
+	#rem monkeydoc Sequence id
 	
 	The sequence id is an integer that is incremented whenever the entity's matrix is modified.
 	
@@ -78,7 +78,7 @@ Class Entity Extends DynamicObject Abstract
 		Return _seq
 	End
 	
-	#rem monkeydoc Entity name.
+	#rem monkeydoc Name
 	#end
 	[jsonify=1]
 	Property Name:String()
@@ -90,7 +90,10 @@ Class Entity Extends DynamicObject Abstract
 		_name=name
 	End
 
-	#rem monkeydoc @hidden
+	#rem monkeydoc Scene
+	
+	The scene the entity belongs to.
+	
 	#end
 	Property Scene:Scene()
 	
@@ -385,6 +388,17 @@ Class Entity Extends DynamicObject Abstract
 	#end
 	Method Destroy()
 		
+		If _scene.Updating
+			If _state<>State.Active Return
+			_state=State.Destroying
+			_scene.UpdateFinished+=Destroy
+			Return
+		End
+		
+		If _state=State.Destroyed Return
+		
+		_state=State.Destroyed
+		
 		While Not _children.Empty
 			_children.Top.Destroy()
 		Wend
@@ -513,7 +527,7 @@ Class Entity Extends DynamicObject Abstract
 		
 		'should really be different pass...ie: ALL entities should be copied before ANY components?
 		For Local c:=Eachin _components
-			c.OnCopy( copy )
+			c.Copy( copy )
 		Next
 		
 		copy.Visible=Visible
@@ -523,8 +537,6 @@ Class Entity Extends DynamicObject Abstract
 		Copied( copy )
 	End
 	
-	Internal
-	
 	Method AddInstance()
 		
 		If _scene.Editing _scene.Jsonifier.AddInstance( Self,New Variant[]( _parent ) )
@@ -540,6 +552,8 @@ Class Entity Extends DynamicObject Abstract
 		If _scene.Editing _scene.Jsonifier.AddInstance( Self,args )
 	End
 	
+	Internal
+	
 	Method AddComponent( c:Component )
 		
 		Local type:=c.Type
@@ -564,52 +578,57 @@ Class Entity Extends DynamicObject Abstract
 		_components.Remove( c )
 	End
 
-	'bottom up
-	Method BeginUpdate()
-
-		For Local e:=Eachin _children
-			e.BeginUpdate()
-		Next
+	Method Start()
 		
 		For Local c:=Eachin _components
-			c.OnBeginUpdate()
+			c.Start()
 		Next
 		
+		For Local e:=Eachin _children
+			e.Start()
+		End
 	End
 	
-	'top down
-	Method Start()
-		
+	Method BeginUpdate()
+
 		For Local c:=Eachin _components
-			c.OnStart()
+			c.BeginUpdate()
 		Next
-		
+
 		For Local e:=Eachin _children
-			e.Start()
-		End
+			e.BeginUpdate()
+		Next
 	End
 	
 	Method Update( elapsed:Float )
 		
 		For Local c:=Eachin _components
-			c.OnUpdate( elapsed )
+			c.Update( elapsed )
 		End
 		
 		For Local e:=Eachin _children
 			e.Update( elapsed )
 		Next
 	End
-	
-	Method Collide( body:RigidBody )
+
+	Method EndUpdate()
 		
 		For Local c:=Eachin _components
-			c.OnCollide( body )
+			c.EndUpdate()
 		Next
-		
-		Collided( body )
-	End
 
+		For Local e:=Eachin _children
+			e.EndUpdate()
+		Next
+	End
+	
 Private
+
+	Enum State
+		Active=1
+		Destroying=2
+		Destroyed=3
+	End
 	
 	Enum Dirty
 		M=1
@@ -632,13 +651,15 @@ Private
 	Field _t:Vec3f=New Vec3f
 	Field _r:Mat3f=New Mat3f
 	Field _s:Vec3f=New Vec3f(1)
-	Field _seq:Int=1
 	
 	Field _dirty:Dirty=Dirty.All
 	Field _M:AffineMat4f
 	Field _W:AffineMat4f
 	Field _IW:AffineMat4f
 	
+	Field _state:State=State.Active
+	Field _seq:Int=1
+	
 	Method InvalidateWorld()
 		
 		If _dirty & Dirty.W Return
@@ -673,8 +694,7 @@ Private
 			OnShow()
 			
 			For Local c:=Eachin _components
-				
-				c.OnShow()
+				c.Show()
 			Next
 		
 		Else
@@ -682,8 +702,7 @@ Private
 			OnHide()
 			
 			For Local c:=Eachin _components
-				
-				c.OnHide()
+				c.Hide()
 			Next
 		Endif
 		

+ 39 - 5
modules/mojo3d/scene/scene.monkey2

@@ -5,6 +5,7 @@ Namespace mojo3d
 #end
 Class Scene
 
+	
 	#rem monkeydoc Creates a new scene.
 	
 	If there is no current scene when a new scene is created, the new scene becomes the current scene.
@@ -32,7 +33,16 @@ Class Scene
 			_editing=True
 		Endif
 	End
+
+	#rem monkeydoc True if scene is currently updating
+	#end	
+	Property Updating:Bool()
+		
+		Return _updating
+	End
 	
+	#rem monkeydoc hidden
+	#end
 	Property World:World()
 		
 		Return _world
@@ -219,7 +229,6 @@ Class Scene
 		_csmSplits=splits.Slice( 0 )
 	End
 	
-	
 	#rem monkeydoc Finds an entity in the scene.
 	
 	Finds an entity in the scene with the given name.
@@ -291,17 +300,19 @@ Class Scene
 	Method Update()
 		
 		If Not _started
+			BeginUpdating()
 			Start()
+			EndUpdating()
 			Return
 		Endif
 		
 		Local now:=Now()
-		
 		_elapsed=now-_time
-		
 		_time=now
 		
+		BeginUpdating()
 		Update( _elapsed )
+		EndUpdating()
 	End
 	
 	#rem monkeydoc Renders the scene to	a canvas.
@@ -416,6 +427,8 @@ Class Scene
 	End
 	
 	Internal
+	
+	Field UpdateFinished:Void()
 
 	Property PostEffects:Stack<PostEffect>()
 		
@@ -482,6 +495,23 @@ Class Scene
 	Field _started:Bool
 	Field _time:Double
 	Field _elapsed:Double
+	Field _updating:Bool
+	
+	Method BeginUpdating()
+		Assert( Not _updating,"Scene.Update cannot be called recursively" )
+		
+		_updating=True
+	End
+	
+	Method EndUpdating()
+		
+		_updating=false
+		
+		Local finished:=UpdateFinished
+		UpdateFinished=Null
+		
+		finished()
+	End
 	
 	Method Update( elapsed:Float )
 		
@@ -489,11 +519,15 @@ Class Scene
 			e.BeginUpdate()
 		Next
 		
-		_world.Update( elapsed )
-		
 		For Local e:=Eachin _rootEntities
 			e.Update( elapsed )
 		Next
+		
+		_world.Update( elapsed )
+
+		For Local e:=Eachin _rootEntities
+			e.EndUpdate()
+		Next
 	End
 			
 End

+ 2 - 11
modules/mojo3d/scene/world.monkey2

@@ -101,18 +101,9 @@ Class World
 			
 			Local body0:=Cast<RigidBody>( p[i*2] )
 			Local body1:=Cast<RigidBody>( p[i*2+1] )
-
-			Local entity0:=body0.Entity
-			Local entity1:=body1.Entity
-			
-			entity0.Collide( body1 )
-			entity1.Collide( body0 )
-			
-'			body0.Entity.Collide( body1 )
-'			body1.Entity.Collide( body0 )
-			
-'			Print "Collision:"+entity0.Name+"->"+entity1.Name
 			
+			body0.Collided( body1 )
+			body1.Collided( body0 )
 		Next
 		
 		resetCollisions()