Răsfoiți Sursa

Animation tweaks + FileStream "asset::" fix.

Mark Sibly 7 ani în urmă
părinte
comite
2da20deaa4

+ 2 - 0
modules/assimp/assimp.monkey2

@@ -146,6 +146,8 @@ End
 
 Class aiAnimation Extends Void
 	
+	Field mName:aiString
+
 	Field mDuration:Double
 	
 	Field mTicksPerSecond:Double

+ 3 - 1
modules/mojo3d-loaders/loaders/assimp.monkey2

@@ -367,7 +367,9 @@ Class AssimpLoader
 		
 		Next
 		
-		Return New Animation( channels,aianim.mDuration,aianim.mTicksPerSecond )
+		Local animation:=New Animation( aianim.mName.data,channels,aianim.mDuration,aianim.mTicksPerSecond,AnimationMode.Looping )
+		
+		Return animation
 	End
 	
 	Method LoadAnimator:Animator( entity:Entity )

+ 32 - 11
modules/mojo3d-loaders/tests/ninja.monkey2

@@ -24,6 +24,8 @@ Class MyWindow Extends Window
 	
 	Field _ninja:Model
 	
+	Field _animator:Animator
+	
 	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
 
 		Super.New( title,width,height,flags )
@@ -39,7 +41,7 @@ Class MyWindow Extends Window
 		_camera.AddComponent<FlyBehaviour>()
 		_camera.Near=.1
 		_camera.Far=100
-		_camera.Move( 0,10,-20 )
+		_camera.Move( 0,5,-7 )
 		
 		'create light
 		'
@@ -55,12 +57,20 @@ Class MyWindow Extends Window
 		'create turtle
 		'		
 		_ninja=Model.LoadBoned( "asset::ninja.b3d" )
+		
+		_animator=_ninja.Animator
+		
+		_ninja.RotateY( 165 )
 '		_ninja.Scale=New Vec3f( .125 )
 
-		Local anim1:=_ninja.Animator.Animations[0].Slice( 1,14 )
-		Local anim2:=_ninja.Animator.Animations[0].Slice( 206,250 )
-		_ninja.Animator.Animations.Add( anim1 )
-		_ninja.Animator.Animations.Add( anim2 )
+		_animator.MasterSpeed=0.5
+
+		Local anim1:=_animator.Animations[0].Slice( "Walk",1,14,AnimationMode.Looping )
+		Local anim2:=_animator.Animations[0].Slice( "Idle",206,250,AnimationMode.Looping )
+		Local anim3:=_animator.Animations[0].Slice( "Attack",134,145,AnimationMode.OneShot )
+		_animator.Animations.Add( anim1 )
+		_animator.Animations.Add( anim2 )
+		_animator.Animations.Add( anim3 )
 		
 	End
 		
@@ -68,19 +78,30 @@ Class MyWindow Extends Window
 		
 		RequestRender()
 		
-		If Keyboard.KeyDown( Key.Enter )
-			_ninja.Animator.Animate( 1,.4,.2 )
-		Else
-			_ninja.Animator.Animate( 2,.4,.2 )
+		If _animator.Animating?.Name<>"Attack"
+			
+			If Keyboard.KeyHit( Key.Space )				'attack!
+				
+				_animator.Animate( "Attack",.2 )
+				
+			Else If Keyboard.KeyDown( Key.Enter )		'walk
+				
+				_animator.Animate( "Walk",.2 )
+			Else										'idle
+				
+				_animator.Animate( "Idle",.2 )
+				
+			Endif
+		
 		Endif
-
+	
 		_scene.Update()
 		
 		_scene.Render( canvas,_camera )
 		
 		canvas.Scale( Width/640.0,Height/480.0 )
 		
-		canvas.DrawText( "Width="+Width+", Height="+Height+", anim time="+_ninja.Animator.Time+", FPS="+App.FPS,0,0 )
+		canvas.DrawText( "Hold [Enter] to strut, [Space] to attack! anim time="+_ninja.Animator.Time,0,0 )
 	End
 	
 End

+ 29 - 4
modules/mojo3d/components/animation.monkey2

@@ -13,14 +13,30 @@ Alias RotationKey:AnimationKey<Quatf>
 #end
 Alias ScaleKey:AnimationKey<Vec3f>
 
+Enum AnimationMode
+	
+	OneShot=1
+	Looping
+	PingPoong
+End
+
 #rem monkeydoc @hidden
 #end
 Class Animation
 	
-	Method New( channels:AnimationChannel[],duration:Float,hertz:Float )
+	Method New( name:String,channels:AnimationChannel[],duration:Float,hertz:Float,mode:AnimationMode )
+		_name=name
 		_channels=channels
 		_duration=duration
 		_hertz=hertz ?Else 24
+		_mode=mode
+	End
+	
+	#rem monkeydoc Animation name.
+	#end
+	Property Name:String()
+		
+		Return _name
 	End
 	
 	#rem monkeydoc Animation channels. 
@@ -53,7 +69,14 @@ Class Animation
 		Return _hertz
 	End
 	
-	Method Slice:Animation( begin:Float,term:Float )
+	#rem monkeydoc Animation mode.
+	#end
+	Property Mode:AnimationMode()
+		
+		Return _mode
+	End
+	
+	Method Slice:Animation( name:String,begin:Float,term:Float,mode:AnimationMode )
 		
 		Local channels:=_channels.Slice( 0 )
 		
@@ -91,7 +114,7 @@ Class Animation
 			channels[i]=New AnimationChannel( posKeys.ToArray(),rotKeys.ToArray(),sclKeys.ToArray() )
 		Next
 		
-		Local animation:=New Animation( channels,duration,_hertz )
+		Local animation:=New Animation( name,channels,duration,_hertz,mode )
 		
 		Return animation
 	End
@@ -110,9 +133,11 @@ Class Animation
 	
 	Private
 	
+	Field _name:String		
 	Field _channels:AnimationChannel[]
 	Field _duration:Float
 	Field _hertz:Float
+	Field _mode:AnimationMode
 End
 
 #rem monkeydoc @hidden
@@ -232,7 +257,7 @@ Class AnimationKey<T>
 	End
 
 	Private
-		
+
 	Field _time:float
 	Field _value:T
 End

+ 78 - 53
modules/mojo3d/components/animator.monkey2

@@ -16,6 +16,8 @@ Class Animator Extends Component
 	
 	Const Type:=New ComponentType( "Animator",0,ComponentTypeFlags.Singleton )
 	
+	Field Finished:Void()
+	
 	Method New( entity:Entity )
 		Super.New( entity,Type )
 	End
@@ -28,10 +30,6 @@ Class Animator Extends Component
 			_skeleton[i]=_skeleton[i].LastCopy
 		End
 		_animations=animator._animations
-		_playing=animator._playing
-		_paused=animator._paused
-		_speed=animator._speed
-		_time=animator._time
 	End
 	
 	Property Skeleton:Entity[]()
@@ -51,12 +49,21 @@ Class Animator Extends Component
 		
 		_animations=animations
 	End
+
+	Property MasterSpeed:Float()
+		
+		Return _speed
 	
-	Property Playing:Bool()
+	Setter( speed:Float )
 		
-		Return _playing<>Null
+		_speed=speed
 	End
 	
+	Property Animating:Animation()
+		
+		Return _playing ? _animation Else Null
+	End
+
 	Property Paused:Bool()
 		
 		Return _paused
@@ -66,15 +73,6 @@ Class Animator Extends Component
 		_paused=paused
 	End
 	
-	Property Speed:Float()
-		
-		Return _speed
-	
-	Setter( speed:Float )
-		
-		_speed=speed
-	End
-	
 	Property Time:Float()
 		
 		Return _time
@@ -84,32 +82,46 @@ Class Animator Extends Component
 		_time=time
 	End
 	
-	Method Animate( animationId:Int,speed:Float=1.0,transition:Float=0.0 )
+	Method FindAnimation:Animation( name:String )
 		
-		DebugAssert( animationId>=0 And animationId<_animations.Length,"Animation id out of range" )
+		For Local animation:=Eachin _animations
+			
+			If animation.Name=name Return animation
+		Next
 		
-		Local anim:=_animations[animationId]
-		If anim<>_playing
-			If _playing And transition>0
-				_playing0=_playing
-				_speed0=_speed
-				_time0=_time
-				_transdur=transition
-				_transtime=0
-				_trans=True
-			Else
-				_trans=False
-			Endif
-			_playing=anim
-			_speed=speed
-			_time=0
+		Return Null
+	End
+	
+	Method Animate( name:String,transition:Float=0.0,finished:Void()=Null )
+		
+		Animate( FindAnimation( name ),transition,finished )
+	End
+		
+	Method Animate( animation:Animation,transition:Float=0.0,finished:Void()=Null )
+		
+		If Not animation return
+		
+		If _playing And _animation=animation Return
+		
+		If _playing And transition>0
+			_animation0=_animation
+			_time0=_time
+			_transition=transition
+			_transtime=0
+			_trans=True
+		Else
+			_trans=False
 		Endif
+		_animation=animation
+		_time=0
+		_finished=finished
+		_playing=True
 		
 	End
 	
 	Method Stop()
 		
-		_playing=Null
+		_playing=False
 	End
 	
 	Protected
@@ -127,20 +139,40 @@ Class Animator Extends Component
 		
 		If _trans
 			_transtime+=elapsed
-			If _transtime<_transdur
-				blend=_transtime/_transdur
+			If _transtime<_transition
+				blend=_transtime/_transition
 			Else
 				_trans=False
 			Endif
 		Endif
 		
-		_time=UpdateTime( _playing,_time,_speed,elapsed )
+		Local duration:=_animation.Duration/_animation.Hertz
+		_time+=_speed*elapsed
+		If _time>=duration
+			Select _animation.Mode
+			Case AnimationMode.OneShot
+				_time=duration
+				_playing=False
+			Case AnimationMode.Looping
+				_time-=duration
+			End
+			_finished()
+		Endif
 		
 		If _trans
-			_time0=UpdateTime( _playing0,_time0,_speed0,elapsed )
-			UpdateSkeleton( _playing0,_time0,_playing,_time,blend )
+			Local duration0:=_animation0.Duration/_animation0.Hertz
+			_time0+=_speed0*elapsed
+			If _time0>=duration0
+				Select _animation0.Mode
+				Case AnimationMode.OneShot
+					_time0=duration0
+				Case AnimationMode.Looping
+					_time0-=duration0
+				End
+			Endif
+			UpdateSkeleton( _animation0,_time0,_animation,_time,blend )
 		Else
-			UpdateSkeleton( _playing,_time,Null,0,0 )
+			UpdateSkeleton( _animation,_time,Null,0,0 )
 		Endif
 		
 	End
@@ -149,31 +181,24 @@ Class Animator Extends Component
 	
 	Field _skeleton:Entity[]
 	Field _animations:=New Stack<Animation>
+	
+	Field _playing:Bool=False
 	Field _paused:Bool=False
 	
 	Field _transtime:Float
-	Field _transdur:Float
+	Field _transition:Float
 	Field _trans:Bool
 	
-	Field _playing0:Animation
+	Field _animation0:Animation
 	Field _speed0:Float
 	Field _time0:Float
 	
-	Field _playing:Animation
+	Field _animation:Animation
 	Field _speed:Float
 	Field _time:Float
-
-	Method UpdateTime:Float( playing:Animation,time:Float,speed:Float,elapsed:Float )
-
-		Local period:=1.0/playing.Hertz
-	
-		time+=elapsed * speed
-	
-		If time>=playing.Duration * period time-=playing.Duration * period Else If time<0 time+=playing.Duration * period
-			
-		Return time
-	End
 	
+	Field _finished:Void()
+
 	Method UpdateSkeleton( playing0:Animation,time0:Float,playing1:Animation,time1:Float,alpha:Float )
 		
 		time0*=playing0?.Hertz

+ 2 - 0
modules/std/stream/filestream.monkey2

@@ -108,6 +108,8 @@ Class FileStream Extends Stream
 			Return Null
 		End
 		
+		path=RealPath( path )
+		
 		Local file:=fopen( path,mode )
 		If Not file Return Null