Browse Source

jsonifier tweaks + Scene.SkyColor.

Mark Sibly 7 years ago
parent
commit
da4b33382e

+ 1 - 0
modules/mojo3d/assets/shaders/imports/std.glsl

@@ -68,6 +68,7 @@ uniform vec4 r_AmbientDiffuse;
 uniform samplerCube r_SkyTextureCube;
 uniform sampler2D r_SkyTexture2D;
 uniform bool r_SkyCube;
+uniform vec4 r_SkyColor;
 
 uniform samplerCube r_EnvTextureCube;
 uniform sampler2D r_EnvTexture2D;

+ 2 - 0
modules/mojo3d/assets/shaders/misc/skybox.glsl

@@ -33,6 +33,8 @@ void main(){
 		frag=pow( texture2D( r_SkyTexture2D,vec2( y,p ) ).rgb,vec3( 2.2 ) );
 	}
 	
+	frag*=r_SkyColor.rgb;
+	
 #if MX2_DEFERREDRENDERER
 	gl_FragData[0]=vec4( frag,1.0 );					//accum
 	gl_FragData[1]=vec4( 0.0,0.0,0.0,1.0 );				//color_m

+ 2 - 1
modules/mojo3d/render/renderer.monkey2

@@ -137,7 +137,7 @@ When a new renderer is created, the config setting `MOJO3D\_RENDERER` can be use
 	Method RenderBackground()
 	
 		If _scene.SkyTexture
-		
+			
 			_gdevice.ColorMask=ColorMask.None
 			_gdevice.DepthMask=True
 			
@@ -1024,6 +1024,7 @@ When a new renderer is created, the config setting `MOJO3D\_RENDERER` can be use
 		Local sky:=_scene.SkyTexture
 		
 		If sky
+			_runiforms.SetColor( "SkyColor",_scene.SkyColor )
 			If sky.Flags & TextureFlags.Cubemap
 				_runiforms.SetTexture( "SkyTextureCube",sky )
 				_runiforms.SetTexture( "SkyTexture2D",_whiteTexture )

+ 23 - 9
modules/mojo3d/scene/entities/model.monkey2

@@ -124,9 +124,9 @@ Class Model Extends Renderable
 		
 		Local scene:=mojo3d.Scene.GetCurrent()
 		
-		Local editing:=scene.Editing
-		
-		If editing scene.Jsonifier.BeginLoading()
+		If scene.Editing
+			scene.Jsonifier.BeginLoading()
+		Endif
 		
 		Local model:Model
 		
@@ -137,9 +137,10 @@ Class Model Extends Renderable
 			If model Exit
 		Next
 		
-		If editing scene.Jsonifier.EndLoading()
-		
-		If editing scene.Jsonifier.AddInstance( model,"mojo3d.Model.Load",New Variant[]( path )  )
+		If scene.Editing
+			scene.Jsonifier.EndLoading()
+			If model scene.Jsonifier.AddInstance( model,"mojo3d.Model.Load",New Variant[]( path )  )
+		Endif
 		
 		Return model
 	End
@@ -161,15 +162,28 @@ Class Model Extends Renderable
 	
 	#end
 	Function LoadBoned:Model( path:String )
+		
+		Local scene:=mojo3d.Scene.GetCurrent()
+		
+		If scene.Editing
+			scene.Jsonifier.BeginLoading()
+		Endif
+		
+		Local model:Model		
 	
 		For Local loader:=Eachin Mojo3dLoader.Instances
 		
-			Local model:=loader.LoadBonedModel( path )
+			model=loader.LoadBonedModel( path )
 			
-			If model Return model
+			If model Exit
 		Next
 		
-		Return Null
+		If scene.Editing
+			scene.Jsonifier.EndLoading()
+			If model scene.Jsonifier.AddInstance( model,"mojo3d.Model.LoadBoned",New Variant[]( path )  )
+		Endif
+		
+		Return model
 	End
 	
 	Protected

+ 50 - 29
modules/mojo3d/scene/jsonifier/jsonifier.monkey2

@@ -5,7 +5,7 @@ Class Jsonifier
 Private
 	
 	Class Instance
-		Field id:Int
+		Field id:String
 		Field obj:Variant
 		Field ctor:Invocation
 		Field initialState:JsonObject
@@ -18,6 +18,7 @@ Private
 	Field _loading:Int
 	Field _instLoading:Int
 	Field _instsByObj:=New Map<Object,Instance>
+	Field _instsById:=New StringMap<Instance>
 	Field _insts:=New Stack<Instance>
 	
 Public
@@ -54,13 +55,16 @@ Public
 			inst.ctor=ctor
 			Return
 		Endif
+		
+		Local id:="#"+_insts.Length
 			
 		inst=New Instance
-		inst.id=_insts.Length
+		inst.id=id
 		inst.obj=obj
 		
-		_insts.Add( inst )
 		_instsByObj[tobj]=inst
+		_instsById[id]=inst
+		_insts.Add( inst )
 		
 		If _loading Return
 
@@ -80,8 +84,6 @@ Public
 		
 		For Local i:=0 Until _insts.Length
 			
-'			Print "Jsonifying "+i
-			
 			Local inst:=_insts[i]
 			Local tobj:=Cast<Object>( inst.obj )
 
@@ -98,13 +100,17 @@ Public
 				If CompareJson( x,y )<>0 dstate[it.Key]=x
 			Next
 			
+			'skip objects with no ctor and no delta state...
 			If Not inst.ctor And dstate.Empty Continue
 			
 			Local jobj:=New JsonObject
+			
 			jobj["type"]=New JsonString( tobj.DynamicType.Name )	'not actually used, cool for debug
 			
-			jobj["id"]=New JsonNumber( inst.id )
+			jobj["id"]=New JsonString( inst.id )
+			
 			If inst.ctor jobj["ctor"]=Jsonify( inst.ctor )
+				
 			If Not dstate.Empty jobj["state"]=dstate
 				
 			jinsts.Add( jobj )
@@ -123,51 +129,65 @@ Public
 		
 		Local jinsts:=jobj.GetArray( "instances" )
 
-		Local jobjsById:=New IntMap<JsonObject>
+		Local jobjsById:=New StringMap<JsonObject>
 		
 		For Local i:=0 Until jinsts.Length
 			
 			Local jobj:=jinsts.GetObject( i )
 			Assert( jobj.Contains( "id" ) )
 			
-			Local id:=jobj.GetNumber( "id" )
+			Local id:=jobj.GetString( "id" )
 			Assert( Not jobjsById.Contains( id ) )
 			
 			jobjsById[id]=jobj
 		Next
 		
-		Local id:=0
+		Local n:=0,ninsts:=_insts.Length
 		
 		For Local i:=0 Until jinsts.Length
 			
 			Local jobj:=jinsts.GetObject( i )
-			If Not jobj.Contains( "ctor" ) Continue
 			
-			If jobj.GetNumber( "id" )>=_insts.Length
+			Local inst:Instance
+			
+			If jobj.Contains( "ctor" ) And i>=ninsts
 				Local ctor:=Cast<Invocation>( Dejsonify( jobj["ctor"],Typeof<Invocation> ) )
-				ctor.Execute()
+				Local tobj:=Cast<Object>( ctor.Execute() )
+				inst=_instsByObj[tobj]
+			Else
+				inst=_insts[i]
 			Endif
 			
-			For Local j:=id Until _insts.Length
-				
-				If Not jobjsById.Contains( j ) Continue
+			Local id:=jobj.GetString( "id" )
+			_instsById[id]=inst
+			inst.id=id
 
-				Local jobj:=jobjsById[j]
+			For Local j:=n Until _insts.Length
+				
+				Local id:=_insts[j].id
+				
+				Local jobj:=jobjsById[id]
+				If Not jobj Or Not jobj.Contains( "state" ) Continue
+				
 				Local tobj:=Cast<Object>( _insts[j].obj )
-				If jobj.Contains( "state" ) DejsonifyState( tobj,jobj.GetObject( "state" ),tobj.DynamicType,False )
+				
+				DejsonifyState( tobj,jobj.GetObject( "state" ),tobj.DynamicType,False )
 			Next
 			
-			id=_insts.Length
+			n=_insts.Length
 		Next
 		
 		'set reference type state - do this on a second pass 'coz of forward refs. Probably wont always work?
-		For Local i:=0 Until _insts.Length
+		For Local j:=0 Until _insts.Length
+			
+			Local id:=_insts[j].id
+			
+			Local jobj:=jobjsById[id]
+			If Not jobj Or Not jobj.Contains( "state" ) Continue
 			
-			If Not jobjsById.Contains( i ) Continue
+			Local tobj:=Cast<Object>( _insts[j].obj )
 			
-			Local jobj:=jobjsById[i]
-			Local tobj:=Cast<Object>( _insts[i].obj )
-			If jobj.Contains( "state" ) DejsonifyState( tobj,jobj.GetObject( "state" ),tobj.DynamicType,True )
+			DejsonifyState( tobj,jobj.GetObject( "state" ),tobj.DynamicType,True )
 		Next
 		
 		SetAssetsDir( assetsDir )
@@ -226,9 +246,10 @@ Public
 			Local obj:=Cast<Object>( value )
 			If Not obj Return JsonValue.NullValue
 			Local inst:=_instsByObj[obj]
-			If inst Return New JsonString( "@"+inst.id )
-			Return JsonValue.NullValue	'for objects that weren't added using AddInstance - should really never happen.
-'			RuntimeError( "Can't jsonify instance of type '"+type+"'" )
+			If inst Return New JsonString( inst.id )
+			'For objects that weren't added using AddInstance, eg: textures loaded via Texture.Load instead of Scene.LoadTexture.
+			Return JsonValue.NullValue	
+'			RuntimeError( "Jsonifier can't find instance of type '"+type+"'" )
 		Endif
 		
 		'try custom jsonifiers
@@ -279,9 +300,9 @@ Public
 			If jvalue.IsNull
 				Return type.NullValue
 			Elseif jvalue.IsString
-				Local id:=Int( jvalue.ToString().Slice( 1 ) )
-				Assert( id>=0 And id<_insts.Length,"Dejsonify error" )
-				Return _insts[id].obj
+				Local id:=jvalue.ToString()
+				Assert( _instsById.Contains( id ),"Dejsonify error" )
+				Return _instsById[id].obj
 			Endif
 		Endif
 		

+ 21 - 0
modules/mojo3d/scene/scene.monkey2

@@ -18,6 +18,8 @@ Class Scene
 		
 		_clearColor=Color.Sky
 
+		_skyColor=Color.White
+
 		_ambientDiffuse=Color.DarkGrey
 		
 		_envColor=Color.White
@@ -55,6 +57,23 @@ Class Scene
 		_skyTexture=texture
 	End
 	
+	#rem monkeydoc The sky color.
+	
+	The sky color is used to modulate the sky texture.
+	
+	Sky color is only used if there is also a sky texture.
+	
+	#end
+	[jsonify=1]
+	Property SkyColor:Color()
+		
+		Return _skyColor
+	
+	Setter( color:Color )
+		
+		_skyColor=color
+	End
+	
 	#rem monkeydoc The environment texture.
 	
 	The environment textures is used to render specular reflections within the scene.
@@ -407,6 +426,8 @@ Class Scene
 	Global _defaultEnv:Texture
 	
 	Field _skyTexture:Texture
+	Field _skyColor:Color
+	
 	Field _envTexture:Texture
 	Field _envColor:Color