public override void CreateScene() { viewport.BackgroundColor = ColorEx.Black; scene.AmbientLight = ColorEx.Gray; Light light = scene.CreateLight( "MainLight" ); light.Position = new Vector3( 20, 80, 50 ); light.Diffuse = ColorEx.Blue; scene.LoadWorldGeometry( "JigLibX_Terrain.xml" ); scene.SetFog( FogMode.Exp2, ColorEx.White, .008f, 0, 250 ); // water plane setup Plane waterPlane = new Plane( Vector3.UnitY, 1.5f ); MeshManager.Instance.CreatePlane( "WaterPlane", ResourceGroupManager.DefaultResourceGroupName, waterPlane, 2800, 2800, 20, 20, true, 1, 10, 10, Vector3.UnitZ ); Entity waterEntity = scene.CreateEntity( "Water", "WaterPlane" ); waterEntity.MaterialName = "Terrain/WaterPlane"; waterNode = scene.RootSceneNode.CreateChildSceneNode( "WaterNode" ); //waterNode.AttachObject( waterEntity ); waterNode.Translate( new Vector3( 1000, 0, 1000 ) ); }
public override void CreateScene() { // set ambient light scene.AmbientLight = ColorEx.Gray; // create a skydome scene.SetSkyDome( true, "Examples/CloudySky", 5, 8 ); // create a light Light light = scene.CreateLight( "MainLight" ); light.Position = new Vector3( 20, 80, 50 ); // add a floor plane Plane p = new Plane(); p.Normal = Vector3.UnitY; p.D = 200; MeshManager.Instance.CreatePlane( "FloorPlane", ResourceGroupManager.DefaultResourceGroupName, p, 2000, 2000, 1, 1, true, 1, 5, 5, Vector3.UnitZ ); // add the floor entity Entity floor = scene.CreateEntity( "Floor", "FloorPlane" ); floor.MaterialName = "Examples/RustySteel"; scene.RootSceneNode.CreateChildSceneNode().AttachObject( floor ); ogre = scene.CreateEntity( "Ogre", "ogrehead.mesh" ); scene.RootSceneNode.CreateChildSceneNode().AttachObject( ogre ); }
public override void ApplyObliqueDepthProjection(ref Matrix4 matrix, Plane plane, bool forGpuProgram) { // Thanks to Eric Lenyel for posting this calculation at www.terathon.com // Calculate the clip-space corner point opposite the clipping plane // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix /* generalised version * Vector4 q = matrix.inverse() * * Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f); */ var q = new Vector4(); q.x = System.Math.Sign(plane.Normal.x) / matrix.m00; q.y = System.Math.Sign(plane.Normal.y) / matrix.m11; q.z = 1.0f; // flip the next bit from Lengyel since we're right-handed if (forGpuProgram) { q.w = (1.0f - matrix.m22) / matrix.m23; } else { q.w = (1.0f + matrix.m22) / matrix.m23; } // Calculate the scaled plane vector var clipPlane4D = new Vector4(plane.Normal.x, plane.Normal.y, plane.Normal.z, plane.D); var c = clipPlane4D * (1.0f / (clipPlane4D.Dot(q))); // Replace the third row of the projection matrix matrix.m20 = c.x; matrix.m21 = c.y; // flip the next bit from Lengyel since we're right-handed if (forGpuProgram) { matrix.m22 = c.z; } else { matrix.m22 = -c.z; } matrix.m23 = c.w; }
public override void CreateScene() { // set some ambient light scene.AmbientLight = new ColorEx( 1.0f, 0.2f, 0.2f, 0.2f ); // create a skydome scene.SetSkyDome( true, "Examples/CloudySky", 5, 8 ); // create a simple default point light Light light = scene.CreateLight( "MainLight" ); light.Position = new Vector3( 20, 80, 50 ); // create a plane for the plane mesh Plane plane = new Plane(); plane.Normal = Vector3.UnitY; plane.D = 200; // create a plane mesh MeshManager.Instance.CreatePlane( "FloorPlane", ResourceGroupManager.DefaultResourceGroupName, plane, 200000, 200000, 20, 20, true, 1, 50, 50, Vector3.UnitZ ); // create an entity to reference this mesh Entity planeEntity = scene.CreateEntity( "Floor", "FloorPlane" ); planeEntity.MaterialName = "Examples/RustySteel"; scene.RootSceneNode.CreateChildSceneNode().AttachObject( planeEntity ); // create an entity to have follow the path Entity ogreHead = scene.CreateEntity( "OgreHead", "ogrehead.mesh" ); // create a scene node for the entity and attach the entity headNode = scene.RootSceneNode.CreateChildSceneNode( "OgreHeadNode", Vector3.Zero, Quaternion.Identity ); headNode.AttachObject( ogreHead ); // make sure the camera tracks this node camera.SetAutoTracking( true, headNode, Vector3.Zero ); // create a scene node to attach the camera to SceneNode cameraNode = scene.RootSceneNode.CreateChildSceneNode( "CameraNode" ); cameraNode.AttachObject( camera ); // turn on some fog scene.SetFog( FogMode.Exp, ColorEx.White, 0.0002f ); }
public override void CreateScene() { // set some ambient light scene.AmbientLight = ColorEx.Gray; Plane plane = new Plane(); // 5000 units from the camera plane.D = 5000; // above the camera, facing down plane.Normal = -Vector3.UnitY; // create the skyplace 10000 units wide, tile the texture 3 times scene.SetSkyPlane( true, plane, "Skyplane/Space", 10000, 3, true, 0, ResourceGroupManager.DefaultResourceGroupName ); // create a default point light Light light = scene.CreateLight( "MainLight" ); light.Position = new Vector3( 20, 80, 50 ); // stuff a dragon into the scene Entity entity = scene.CreateEntity( "dragon", "dragon.mesh" ); scene.RootSceneNode.AttachObject( entity ); }
/// <summary> /// Enables / disables a 'sky plane' i.e. a plane at constant /// distance from the camera representing the sky. /// </summary> /// <param name="enable">True to enable the plane, false to disable it.</param> /// <param name="plane">Details of the plane, i.e. it's normal and it's distance from the camera.</param> /// <param name="materialName">The name of the material the plane will use.</param> /// <param name="scale">The scaling applied to the sky plane - higher values mean a bigger sky plane.</param> /// <param name="tiling">How many times to tile the texture across the sky.</param> /// <param name="drawFirst"> /// If true, the plane is drawn before all other geometry in the scene, without updating the depth buffer. /// This is the safest rendering method since all other objects /// will always appear in front of the sky. However this is not /// the most efficient way if most of the sky is often occluded /// by other objects. If this is the case, you can set this /// parameter to false meaning it draws <em>after</em> all other /// geometry which can be an optimisation - however you must /// ensure that the plane.d value is large enough that no objects /// will 'poke through' the sky plane when it is rendered. /// </param> /// <param name="bow"> /// If above zero, the plane will be curved, allowing /// the sky to appear below camera level. Curved sky planes are /// simular to skydomes, but are more compatable with fog. /// </param> /// <param name="groupName"></param> public virtual void SetSkyPlane( bool enable, Plane plane, string materialName, float scale, float tiling, bool drawFirst, float bow, string groupName ) { this.isSkyPlaneEnabled = enable; if ( enable ) { string meshName = "SkyPlane"; this.skyPlane = plane; Material m = (Material)MaterialManager.Instance[ materialName ]; if ( m == null ) { throw new AxiomException( string.Format( "Skyplane material '{0}' not found.", materialName ) ); } // make sure the material doesn't update the depth buffer m.DepthWrite = false; m.Load(); this.isSkyPlaneDrawnFirst = drawFirst; // set up the place Mesh planeMesh = (Mesh)MeshManager.Instance[ meshName ]; // unload the old one if it exists if ( planeMesh != null ) { MeshManager.Instance.Unload( planeMesh ); } // create up vector Vector3 up = plane.Normal.Cross( Vector3.UnitX ); if ( up == Vector3.Zero ) { up = plane.Normal.Cross( -Vector3.UnitZ ); } if ( bow > 0 ) { planeMesh = MeshManager.Instance.CreateCurvedIllusionPlane( meshName, groupName, plane, scale * 100, scale * 100, scale * bow * 100, 6, 6, false, 1, tiling, tiling, up ); } else { planeMesh = MeshManager.Instance.CreatePlane( meshName, groupName, plane, scale * 100, scale * 100, 1, 1, false, 1, tiling, tiling, up ); } if ( this.skyPlaneEntity != null ) { this.RemoveEntity( this.skyPlaneEntity ); } // create entity for the plane, using the mesh name this.skyPlaneEntity = CreateEntity( meshName, meshName ); this.skyPlaneEntity.MaterialName = materialName; // sky entities need not cast shadows this.skyPlaneEntity.CastShadows = false; if ( this.skyPlaneNode == null ) { this.skyPlaneNode = this.CreateSceneNode( meshName + "Node" ); } else { this.skyPlaneNode.DetachAllObjects(); } // attach the skyplane to the new node this.skyPlaneNode.AttachObject( this.skyPlaneEntity ); } }
/// <summary> /// Utility method for creating the planes of a skybox. /// </summary> /// <param name="plane"></param> /// <param name="distance"></param> /// <param name="orientation"></param> /// <param name="groupName"></param> /// <returns></returns> protected Mesh CreateSkyboxPlane( BoxPlane plane, float distance, Quaternion orientation, string groupName ) { Plane p = new Plane(); string meshName = "SkyboxPlane_"; Vector3 up = Vector3.Zero; // set the distance of the plane p.D = distance; switch ( plane ) { case BoxPlane.Front: p.Normal = Vector3.UnitZ; up = Vector3.UnitY; meshName += "Front"; break; case BoxPlane.Back: p.Normal = -Vector3.UnitZ; up = Vector3.UnitY; meshName += "Back"; break; case BoxPlane.Left: p.Normal = Vector3.UnitX; up = Vector3.UnitY; meshName += "Left"; break; case BoxPlane.Right: p.Normal = -Vector3.UnitX; up = Vector3.UnitY; meshName += "Right"; break; case BoxPlane.Up: p.Normal = -Vector3.UnitY; up = Vector3.UnitZ; meshName += "Up"; break; case BoxPlane.Down: p.Normal = Vector3.UnitY; up = -Vector3.UnitZ; meshName += "Down"; break; } // modify by orientation p.Normal = orientation * p.Normal; up = orientation * up; MeshManager modelMgr = MeshManager.Instance; // see if this mesh exists Mesh planeModel = (Mesh)modelMgr[ meshName ]; // trash it if it already exists if ( planeModel != null ) { modelMgr.Unload( planeModel ); } float planeSize = distance * 2; // create and return the plane mesh return modelMgr.CreatePlane( meshName, groupName, p, planeSize, planeSize, 1, 1, false, 1, 1, 1, up ); }
/// <summary> /// /// </summary> /// <param name="plane"></param> /// <returns>True if the plane intersects, false otherwise.</returns> public bool Intersects( Plane plane ) { return Utility.Intersects( plane, this ); }
/// <summary> /// </summary> public Mesh CreateCurvedIllusionPlane( string name, string group, Plane plane, float width, float height, float curvature, int xSegments, int ySegments, bool normals, int texCoordSetCount, float xTiles, float yTiles, Vector3 upVector, Quaternion orientation, BufferUsage vertexBufferUsage, BufferUsage indexBufferUsage, bool vertexShadowBuffer, bool indexShadowBuffer, int ySegmentsToKeep ) { // Create manual mesh which calls back self to load Mesh mesh = CreateManual( name, group, this ); // Planes can never be manifold mesh.AutoBuildEdgeLists = false; // store parameters MeshBuildParams meshParams = new MeshBuildParams(); meshParams.Type = MeshBuildType.Plane; meshParams.Plane = plane; meshParams.Width = width; meshParams.Height = height; meshParams.Curvature = curvature; meshParams.XSegments = xSegments; meshParams.YSegments = ySegments; meshParams.Normals = normals; meshParams.TexCoordSetCount = texCoordSetCount; meshParams.XTile = xTiles; meshParams.YTile = yTiles; meshParams.Orientation = orientation; meshParams.UpVector = upVector; meshParams.VertexBufferUsage = vertexBufferUsage; meshParams.IndexBufferUsage = indexBufferUsage; meshParams.VertexShadowBuffer = vertexShadowBuffer; meshParams.IndexShadowBuffer = indexShadowBuffer; meshParams.YSegmentsToKeep = ySegmentsToKeep; _meshBuildParams.Add( mesh, meshParams ); // to preserve previous behaviour, load immediately mesh.Load(); return mesh; }
/// <summary> /// </summary> public Mesh CreateCurvedPlane( string name, string group, Plane plane, float width, float height, Real bow, int xSegments, int ySegments, bool normals, int texCoordSetCount, float xTile, float yTile, Vector3 upVec ) { return CreateCurvedPlane( name, group, plane, width, height, bow, xSegments, ySegments, normals, texCoordSetCount, xTile, yTile, upVec, BufferUsage.StaticWriteOnly, BufferUsage.StaticWriteOnly, true, true ); }
/// <summary> /// Overloaded method. /// </summary> /// <param name="name">Name of the plane mesh.</param> ///<param name="group"></param> ///<param name="plane">Plane to use for distance and orientation of the mesh.</param> /// <param name="width">Width in world coordinates.</param> /// <param name="height">Height in world coordinates.</param> /// <returns></returns> public Mesh CreatePlane( string name, string group, Plane plane, int width, int height ) { return CreatePlane( name, group, plane, width, height, 1, 1, true, 1, 1.0f, 1.0f, Vector3.UnitY, BufferUsage.StaticWriteOnly, BufferUsage.StaticWriteOnly, true, true ); }
/// <summary> /// Sets up the samples content /// </summary> protected override void SetupContent() { // set some ambient light SceneManager.AmbientLight = new ColorEx( 1.0f, 0.2f, 0.2f, 0.2f ); // create a skydome SceneManager.SetSkyDome( true, "Examples/CloudySky", 5, 8 ); // create a simple default point light Light light = SceneManager.CreateLight( "MainLight" ); light.Position = new Vector3( 20, 80, 50 ); // create a plane for the plane mesh Plane plane = new Plane(); plane.Normal = Vector3.UnitY; plane.D = 200; // create a plane mesh MeshManager.Instance.CreatePlane( "FloorPlane", ResourceGroupManager.DefaultResourceGroupName, plane, 200000, 200000, 20, 20, true, 1, 50, 50, Vector3.UnitZ ); // create an entity to reference this mesh Entity planeEntity = SceneManager.CreateEntity( "Floor", "FloorPlane" ); planeEntity.MaterialName = "Examples/RustySteel"; SceneManager.RootSceneNode.CreateChildSceneNode().AttachObject( planeEntity ); // create an entity to have follow the path Entity ogreHead = SceneManager.CreateEntity( "OgreHead", "ogrehead.mesh" ); // Load muiltiple heads for box select and demonstrating single select with stacked objects // create a scene node for each entity and attach the entity SceneNode ogreHead1Node; ogreHead1Node = SceneManager.RootSceneNode.CreateChildSceneNode( "OgreHeadNode", Vector3.Zero, Quaternion.Identity ); ogreHead1Node.AttachObject( ogreHead ); SceneNode ogreHead2Node; Entity ogreHead2 = SceneManager.CreateEntity( "OgreHead2", "ogrehead.mesh" ); ogreHead2Node = SceneManager.RootSceneNode.CreateChildSceneNode( "OgreHead2Node", new Vector3( -100, 0, 0 ), Quaternion.Identity ); ogreHead2Node.AttachObject( ogreHead2 ); SceneNode ogreHead3Node; Entity ogreHead3 = SceneManager.CreateEntity( "OgreHead3", "ogrehead.mesh" ); ogreHead3Node = SceneManager.RootSceneNode.CreateChildSceneNode( "OgreHead3Node", new Vector3( +100, 0, 0 ), Quaternion.Identity ); ogreHead3Node.AttachObject( ogreHead3 ); // make sure the camera tracks this node // set initial camera position CameraManager.setStyle( CameraStyle.FreeLook ); Camera.Position = new Vector3( 0, 0, 500 ); Camera.SetAutoTracking( true, ogreHead1Node, Vector3.Zero ); // create a scene node to attach the camera to SceneNode cameraNode = SceneManager.RootSceneNode.CreateChildSceneNode( "CameraNode" ); cameraNode.AttachObject( Camera ); // turn on some fog SceneManager.SetFog( FogMode.Exp, ColorEx.White, 0.0002f ); _MouseSelector = new MouseSelector( "MouseSelector", Camera, Window ); _MouseSelector.SelectionMode = MouseSelector.SelectionModeType.None; SetupGUI(); initialized = true; base.SetupContent(); }
public void CalculateMinLevelDist2( Real C ) #endif { //level 0 has no delta. this.mMinLevelDistSqr[ 0 ] = 0; int i, j; for ( var level = 1; level < this.mOptions.maxGeoMipMapLevel; level++ ) { this.mMinLevelDistSqr[ level ] = 0; var step = 1 << level; // The step of the next higher LOD var higherstep = step >> 1; #if AXIOM_SAFE_ONLY ITypePointer<float> pDeltas = null; #else float* pDeltas = null; #endif BufferBase dataPtr; if ( this.mOptions.lodMorph ) { // Create a set of delta values (store at index - 1 since 0 has none) this.mDeltaBuffers[ level - 1 ] = CreateDeltaBuffer(); // Lock, but don't discard (we want the pre-initialised zeros) dataPtr = this.mDeltaBuffers[ level - 1 ].Lock( BufferLocking.Normal ); pDeltas = dataPtr.ToFloatPointer(); } for ( j = 0; j < this.mOptions.tileSize - step; j += step ) { for ( i = 0; i < this.mOptions.tileSize - step; i += step ) { /* Form planes relating to the lower detail tris to be produced For tri lists and even tri strip rows, they are this shape: x---x | / | x---x For odd tri strip rows, they are this shape: x---x | \ | x---x */ var v1 = new Vector3( Vertex( i, j, 0 ), Vertex( i, j, 1 ), Vertex( i, j, 2 ) ); var v2 = new Vector3( Vertex( i + step, j, 0 ), Vertex( i + step, j, 1 ), Vertex( i + step, j, 2 ) ); var v3 = new Vector3( Vertex( i, j + step, 0 ), Vertex( i, j + step, 1 ), Vertex( i, j + step, 2 ) ); var v4 = new Vector3( Vertex( i + step, j + step, 0 ), Vertex( i + step, j + step, 1 ), Vertex( i + step, j + step, 2 ) ); Plane t1, t2; t1 = new Plane(); t2 = new Plane(); var backwardTri = false; if ( !this.mOptions.useTriStrips || j%2 == 0 ) { t1.Redefine( v1, v3, v2 ); t2.Redefine( v2, v3, v4 ); } else { t1.Redefine( v1, v3, v4 ); t2.Redefine( v1, v4, v2 ); backwardTri = true; } // include the bottommost row of vertices if this is the last row var zubound = ( j == ( this.mOptions.tileSize - step ) ? step : step - 1 ); for ( var z = 0; z <= zubound; z++ ) { // include the rightmost col of vertices if this is the last col var xubound = ( i == ( this.mOptions.tileSize - step ) ? step : step - 1 ); for ( var x = 0; x <= xubound; x++ ) { var fulldetailx = i + x; var fulldetailz = j + z; if ( fulldetailx%step == 0 && fulldetailz%step == 0 ) { // Skip, this one is a vertex at this level continue; } var zpct = (Real)z/(Real)step; var xpct = (Real)x/(Real)step; //interpolated height var actualPos = new Vector3( Vertex( fulldetailx, fulldetailz, 0 ), Vertex( fulldetailx, fulldetailz, 1 ), Vertex( fulldetailx, fulldetailz, 2 ) ); Real interp_h; // Determine which tri we're on if ( ( xpct + zpct <= 1.0f && !backwardTri ) || ( xpct + ( 1 - zpct ) <= 1.0f && backwardTri ) ) { // Solve for x/z interp_h = ( -( t1.Normal.x*actualPos.x ) - t1.Normal.z*actualPos.z - t1.D )/t1.Normal.y; } else { // Second tri interp_h = ( -( t2.Normal.x*actualPos.x ) - t2.Normal.z*actualPos.z - t2.D )/t2.Normal.y; } Real actual_h = Vertex( fulldetailx, fulldetailz, 1 ); //Check: not sure about fabs used here... Real delta = Math.Abs( interp_h - actual_h ); var D2 = delta*delta*C*C; if ( this.mMinLevelDistSqr[ level ] < D2 ) { this.mMinLevelDistSqr[ level ] = D2; } // Should be save height difference? // Don't morph along edges if ( this.mOptions.lodMorph && fulldetailx != 0 && fulldetailx != ( this.mOptions.tileSize - 1 ) && fulldetailz != 0 && fulldetailz != ( this.mOptions.tileSize - 1 ) ) { // Save height difference pDeltas[ (int)( fulldetailx + ( fulldetailz*this.mOptions.tileSize ) ) ] = interp_h - actual_h; } } } } } // Unlock morph deltas if required if ( this.mOptions.lodMorph ) { this.mDeltaBuffers[ level - 1 ].Unlock(); } } // Post validate the whole set for ( i = 1; i < this.mOptions.maxGeoMipMapLevel; i++ ) { // Make sure no LOD transition within the tile // This is especially a problem when using large tiles with flat areas /* Hmm, this can look bad on some areas, disable for now Vector3 delta(_vertex(0,0,0), mCenter.y, _vertex(0,0,2)); delta = delta - mCenter; Real minDist = delta.squaredLength(); mMinLevelDistSqr[ i ] = std::max(mMinLevelDistSqr[ i ], minDist); */ //make sure the levels are increasing... if ( this.mMinLevelDistSqr[ i ] < this.mMinLevelDistSqr[ i - 1 ] ) { this.mMinLevelDistSqr[ i ] = this.mMinLevelDistSqr[ i - 1 ]; } } // Now reverse traverse the list setting the 'next level down' Real lastDist = -1; var lastIndex = 0; for ( i = this.mOptions.maxGeoMipMapLevel - 1; i >= 0; --i ) { if ( i == this.mOptions.maxGeoMipMapLevel - 1 ) { // Last one is always 0 lastIndex = i; lastDist = this.mMinLevelDistSqr[ i ]; this.mNextLevelDown[ i ] = 0; } else { this.mNextLevelDown[ i ] = lastIndex; if ( this.mMinLevelDistSqr[ i ] != lastDist ) { lastIndex = i; lastDist = this.mMinLevelDistSqr[ i ]; } } } }
public override void ApplyObliqueDepthProjection( ref Matrix4 matrix, Plane plane, bool forGpuProgram ) { // Thanks to Eric Lenyel for posting this calculation at www.terathon.com // Calculate the clip-space corner point opposite the clipping plane // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix var q = new Vector4(); q.x = ( Utility.Sign( plane.Normal.x ) + matrix[ 0, 2 ] ) / matrix[ 0, 0 ]; q.y = ( Utility.Sign( plane.Normal.y ) + matrix[ 1, 2 ] ) / matrix[ 1, 1 ]; q.z = -1.0f; q.w = ( 1.0f + matrix[ 2, 2 ] ) / matrix[ 2, 3 ]; //Calculate the scaled plane vector var clipPlane4D = new Vector4( plane.Normal.x, plane.Normal.y, plane.Normal.z, plane.D ); Vector4 c = clipPlane4D * ( 2.0f / ( clipPlane4D.Dot( q ) ) ); //Replace the thrid row of the projection matrix matrix[ 2, 0 ] = c.x; matrix[ 2, 1 ] = c.y; matrix[ 2, 2 ] = c.z + 1.0f; matrix[ 2, 3 ] = c.w; }
public override void CreateScene() { // Register Compositor Logics CompositorManager.Instance.RegisterCompositorLogic( "HDR", new HdrLogic() ); scene.ShadowTechnique = ShadowTechnique.TextureModulative; scene.ShadowFarDistance = 1000; scene.AmbientLight = new ColorEx( 0.3f, 0.3f, 0.2f ); Light light = scene.CreateLight( "Light2" ); Vector3 dir = new Vector3( -1, -1, 0 ); dir.Normalize(); light.Type = LightType.Directional; light.Direction = dir; light.Diffuse = new ColorEx( 1.0f, 1.0f, 0.8f ); light.Specular = new ColorEx( 1.0f, 1.0f, 1.0f ); Entity entity; // House entity = scene.CreateEntity( "1", "tudorhouse.mesh" ); SceneNode n1 = scene.RootSceneNode.CreateChildSceneNode( new Vector3( 350, 450, -200 ) ); n1.AttachObject( entity ); entity = scene.CreateEntity( "2", "tudorhouse.mesh" ); SceneNode n2 = scene.RootSceneNode.CreateChildSceneNode( new Vector3( -350, 450, -200 ) ); n2.AttachObject( entity ); entity = scene.CreateEntity( "3", "knot.mesh" ); _spinny = scene.RootSceneNode.CreateChildSceneNode( new Vector3( 0, 0, 300 ) ); _spinny.AttachObject( entity ); entity.MaterialName = "Examples/MorningCubeMap"; scene.SetSkyBox( true, "Examples/MorningSkyBox", 50 ); Plane plane = new Plane(); plane.Normal = Vector3.UnitY; plane.D = 100; MeshManager.Instance.CreatePlane( "Myplane", ResourceGroupManager.DefaultResourceGroupName, plane, 1500, 1500, 10, 10, true, 1, 5, 5, Vector3.UnitZ ); Entity planeEntity = scene.CreateEntity( "plane", "Myplane" ); planeEntity.MaterialName = "Examples/Rockwall"; planeEntity.CastShadows = false; scene.RootSceneNode.CreateChildSceneNode().AttachObject( planeEntity ); camera.Position = new Vector3( -400, 50, 900 ); camera.LookAt( new Vector3( 0, 80, 0 ) ); /// Create a couple of hard coded postfilter effects as an example of how to do it /// but the preferred method is to use compositor scripts. _createEffects(); foreach ( string name in _compositorList ) { CompositorManager.Instance.AddCompositor( this.window.GetViewport( 0 ), name ); } //CompositorManager.Instance.SetCompositorEnabled(this.window.GetViewport(0), // _compositorList[_compositorList.Length - 2], // true); CompositorManager.Instance.SetCompositorEnabled( this.window.GetViewport( 0 ), _compositorList[ 0 ], true ); }
public override void ApplyObliqueDepthProjection( ref Matrix4 matrix, Plane plane, bool forGpuProgram ) { // Thanks to Eric Lenyel for posting this calculation at www.terathon.com // Calculate the clip-space corner point opposite the clipping plane // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix /* generalised version Vector4 q = matrix.inverse() * Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f); */ var q = new Vector4(); q.x = System.Math.Sign( plane.Normal.x )/matrix.m00; q.y = System.Math.Sign( plane.Normal.y )/matrix.m11; q.z = 1.0f; // flip the next bit from Lengyel since we're right-handed if ( forGpuProgram ) { q.w = ( 1.0f - matrix.m22 )/matrix.m23; } else { q.w = ( 1.0f + matrix.m22 )/matrix.m23; } // Calculate the scaled plane vector var clipPlane4D = new Vector4( plane.Normal.x, plane.Normal.y, plane.Normal.z, plane.D ); var c = clipPlane4D*( 1.0f/( clipPlane4D.Dot( q ) ) ); // Replace the third row of the projection matrix matrix.m20 = c.x; matrix.m21 = c.y; // flip the next bit from Lengyel since we're right-handed if ( forGpuProgram ) { matrix.m22 = c.z; } else { matrix.m22 = -c.z; } matrix.m23 = c.w; }
/// <summary> /// /// </summary> protected void SetupScene() { // Set ambient light SceneManager.AmbientLight = new ColorEx( 0.3f, 0.3f, 0.3f ); SceneManager.SetSkyBox( true, "SkyBox", 1000 ); this.mainNode = SceneManager.RootSceneNode.CreateChildSceneNode(); for ( int i = 0; i < NumLights; ++i ) { this.lightPivots[ i ] = SceneManager.RootSceneNode.CreateChildSceneNode(); this.lightPivots[ i ].Rotate( this.lightRotationAxes[ i ], this.lightRotationAngles[ i ] ); // Create a light, use default parameters this.lights[ i ] = SceneManager.CreateLight( "Light" + i ); this.lights[ i ].Position = this.lightPositions[ i ]; this.lights[ i ].Diffuse = this.diffuseLightColors[ i ]; this.lights[ i ].Specular = this.specularLightColors[ i ]; this.lights[ i ].IsVisible = this.lightState[ i ]; //lights[i]->setAttenuation(400, 0.1 , 1 , 0); // Attach light this.lightPivots[ i ].AttachObject( this.lights[ i ] ); // Create billboard for light this.lightFlareSets[ i ] = SceneManager.CreateBillboardSet( "Flare" + i ); this.lightFlareSets[ i ].MaterialName = "LightFlare"; this.lightPivots[ i ].AttachObject( this.lightFlareSets[ i ] ); this.lightFlares[ i ] = this.lightFlareSets[ i ].CreateBillboard( this.lightPositions[ i ] ); this.lightFlares[ i ].Color = this.diffuseLightColors[ i ]; this.lightFlareSets[ i ].IsVisible = this.lightState[ i ]; } // move the camera a bit right and make it look at the knot Camera.MoveRelative( new Vector3( 50, 0, 100 ) ); Camera.LookAt( new Vector3( 0, 10, 0 ) ); // Define a plane mesh that will be used for the ocean surface var oceanSurface = new Plane( Vector3.UnitY, 20 ); MeshManager.Instance.CreatePlane( "OceanSurface", ResourceGroupManager.DefaultResourceGroupName, oceanSurface, 1000, 1000, 50, 50, true, 1, 1, 1, Vector3.UnitZ ); this.oceanSurfaceEnt = SceneManager.CreateEntity( "OceanSurface", "OceanSurface" ); SceneManager.RootSceneNode.CreateChildSceneNode().AttachObject( this.oceanSurfaceEnt ); this.oceanSurfaceEnt.MaterialName = this.materialControlsContainer[ 0 ].MaterialName; }
/// <summary> /// </summary> public Mesh CreateCurvedPlane( string name, string group, Plane plane, float width, float height ) { return CreateCurvedPlane( name, group, plane, width, height, 0.5f, 1, 1, false, 1, 1.0f, 1.0f, Vector3.UnitY, BufferUsage.StaticWriteOnly, BufferUsage.StaticWriteOnly, true, true ); }
/// <summary> /// Returns whether or not this sphere interects a plane. /// </summary> /// <param name="plane"></param> /// <returns>True if the plane intersects, false otherwise.</returns> public bool Intersects( Plane plane ) { return Utility.Intersects( this, plane ); }
/// <summary> /// </summary> public Mesh CreateCurvedIllusionPlane( string name, string group, Plane plane, float width, float height, float curvature, int xSegments, int ySegments, bool normals, int texCoordSetCount, float xTiles, float yTiles, Vector3 upVector, Quaternion orientation, BufferUsage vertexBufferUsage, BufferUsage indexBufferUsage, bool vertexShadowBuffer, bool indexShadowBuffer ) { return CreateCurvedIllusionPlane( name, group, plane, width, height, curvature, xSegments, ySegments, normals, texCoordSetCount, xTiles, yTiles, upVector, Quaternion.Identity, BufferUsage.StaticWriteOnly, BufferUsage.StaticWriteOnly, vertexShadowBuffer, indexShadowBuffer, -1 ); }
public bool CalculateTexCoordsAndColors( Plane plane, Vector3[] vertices, out Vector2[] texCoors, out ColorEx[] colors ) { switch ( this.Type ) { case LightType.Directional: return CalculateForDirectionalLight( plane, vertices, out texCoors, out colors ); case LightType.Point: return CalculateForPointLight( plane, vertices, out texCoors, out colors ); case LightType.Spotlight: return CalculateForSpotLight( plane, vertices, out texCoors, out colors ); } texCoors = null; colors = null; return false; }
//public Plane() //{ // this.Normal = Vector3.Zero; // this.D = Real.NaN; //} public Plane( Plane plane ) { this.Normal = plane.Normal; this.D = plane.D; }
protected bool CalculateForPointLight( Plane plane, Vector3[] vertices, out Vector2[] texCoors, out ColorEx[] colors ) { texCoors = new Vector2[ vertices.Length ]; colors = new ColorEx[ vertices.Length ]; Vector3 lightPos, faceLightPos; lightPos = this.GetDerivedPosition(); float dist = plane.GetDistance( lightPos ); if ( Utility.Abs( dist ) < range ) { // light is visible //light pos on face faceLightPos = lightPos - plane.Normal * dist; Vector3 verAxis = plane.Normal.Perpendicular(); Vector3 horAxis = verAxis.Cross( plane.Normal ); Plane verPlane = new Plane( verAxis, faceLightPos ); Plane horPlane = new Plane( horAxis, faceLightPos ); float lightRadiusSqr = range * range; float relRadiusSqr = lightRadiusSqr - dist * dist; float relRadius = Utility.Sqrt( relRadiusSqr ); float scale = 0.5f / relRadius; float brightness = relRadiusSqr / lightRadiusSqr; ColorEx lightCol = new ColorEx( brightness * textureColor.a, textureColor.r, textureColor.g, textureColor.b ); for ( int i = 0; i < vertices.Length; i++ ) { texCoors[ i ].x = horPlane.GetDistance( vertices[ i ] ) * scale + 0.5f; texCoors[ i ].y = verPlane.GetDistance( vertices[ i ] ) * scale + 0.5f; colors[ i ] = lightCol; } return true; } return false; }
public virtual void ForwardIntersect( Plane worldPlane, IList<Vector4> intersect3D ) { if ( intersect3D == null ) { return; } var trCorner = WorldSpaceCorners[ 0 ]; var tlCorner = WorldSpaceCorners[ 1 ]; var blCorner = WorldSpaceCorners[ 2 ]; var brCorner = WorldSpaceCorners[ 3 ]; // need some sort of rotation that will bring the plane normal to the z axis var pval = worldPlane; if ( pval.Normal.z < 0.0 ) { pval.Normal *= -1.0; pval.D *= -1.0; } var invPlaneRot = pval.Normal.GetRotationTo( Vector3.UnitZ ); var vec = new Vector3[4]; // get rotated light var lPos = invPlaneRot*DerivedPosition; vec[ 0 ] = invPlaneRot*trCorner - lPos; vec[ 1 ] = invPlaneRot*tlCorner - lPos; vec[ 2 ] = invPlaneRot*blCorner - lPos; vec[ 3 ] = invPlaneRot*brCorner - lPos; var iPnt = GetRayForwardIntersect( lPos, vec, -pval.D ); // return wanted data //if (intersect3D != null) // cant be null { var planeRot = invPlaneRot.Inverse(); intersect3D.Clear(); foreach ( var v in iPnt ) { var intersection = planeRot*new Vector3( v.x, v.y, v.z ); intersect3D.Add( new Vector4( intersection.x, intersection.y, intersection.z, v.w ) ); } } }
protected bool CalculateForSpotLight( Plane plane, Vector3[] vertices, out Vector2[] texCoors, out ColorEx[] colors ) { texCoors = new Vector2[ vertices.Length ]; colors = new ColorEx[ vertices.Length ]; ColorEx lightCol = new ColorEx( textureColor.a, textureColor.r, textureColor.g, textureColor.b ); for ( int i = 0; i < vertices.Length; i++ ) { colors[ i ] = lightCol; } return true; }
public override void CreateScene() { // set ambient light scene.AmbientLight = new ColorEx( 0.2f, 0.2f, 0.2f ); scene.SetSkyBox( true, "Skybox/Morning", 5000 ); // create a default point light Light light = scene.CreateLight( "MainLight" ); light.Type = LightType.Directional; Vector3 dir = new Vector3( 0.5f, -1, 0 ); dir.Normalize(); light.Direction = dir; light.Diffuse = new ColorEx( 1.0f, 1.0f, 0.8f ); light.Specular = ColorEx.White; // create a plane plane = new MovablePlane( "ReflectPlane" ); plane.D = 0; plane.Normal = Vector3.UnitY; // create another plane to create the mesh. Ogre's MovablePlane uses multiple inheritance, bah! Plane tmpPlane = new Plane(); tmpPlane.D = 0; tmpPlane.Normal = Vector3.UnitY; MeshManager.Instance.CreatePlane( "ReflectionPlane", ResourceGroupManager.DefaultResourceGroupName, tmpPlane, 2000, 2000, 1, 1, true, 1, 1, 1, Vector3.UnitZ ); planeEntity = scene.CreateEntity( "Plane", "ReflectionPlane" ); // create an entity from a model Entity knot = scene.CreateEntity( "Knot", "knot.mesh" ); knot.MaterialName = "TextureFX/Knot"; // create an entity from a model Entity head = scene.CreateEntity( "Head", "ogrehead.mesh" ); // attach the render to texture entity to the root of the scene SceneNode rootNode = scene.RootSceneNode; planeNode = rootNode.CreateChildSceneNode(); planeNode.AttachObject( planeEntity ); planeNode.AttachObject( plane ); planeNode.Translate( new Vector3( 0, -10, 0 ) ); // tilt it a little to make it interesting planeNode.Roll( 5 ); rootNode.CreateChildSceneNode( "Head" ).AttachObject( head ); // create a render texture Texture texture = TextureManager.Instance.CreateManual( "RttTex", ResourceGroupManager.DefaultResourceGroupName, TextureType.TwoD, 512, 512, 0, Axiom.Media.PixelFormat.R8G8B8, TextureUsage.RenderTarget ); RenderTarget rttTex = texture.GetBuffer().GetRenderTarget(); reflectCam = scene.CreateCamera( "ReflectCam" ); reflectCam.Near = camera.Near; reflectCam.Far = camera.Far; reflectCam.AspectRatio = (float)window.GetViewport( 0 ).ActualWidth / (float)window.GetViewport( 0 ).ActualHeight; Viewport viewport = rttTex.AddViewport( reflectCam ); viewport.SetClearEveryFrame( true ); viewport.ShowOverlays = false; viewport.BackgroundColor = ColorEx.Black; Material mat = (Material)MaterialManager.Instance.Create( "RttMat", ResourceGroupManager.DefaultResourceGroupName ); TextureUnitState t = mat.GetTechnique( 0 ).GetPass( 0 ).CreateTextureUnitState( "RustedMetal.jpg" ); t = mat.GetTechnique( 0 ).GetPass( 0 ).CreateTextureUnitState( "RttTex" ); // blend with base texture t.SetColorOperationEx( LayerBlendOperationEx.BlendManual, LayerBlendSource.Texture, LayerBlendSource.Current, ColorEx.White, ColorEx.White, 0.25f ); t.SetProjectiveTexturing( true, reflectCam ); // register events for viewport before/after update rttTex.AfterUpdate += new RenderTargetEventHandler( rttTex_AfterUpdate ); rttTex.BeforeUpdate += new RenderTargetEventHandler( rttTex_BeforeUpdate ); // set up linked reflection reflectCam.EnableReflection( plane ); // also clip reflectCam.EnableCustomNearClipPlane( plane ); planeEntity.MaterialName = "RttMat"; Entity clone = null; for ( int i = 0; i < 10; i++ ) { // create a new node under the root SceneNode node = scene.CreateSceneNode(); // calculate a random position Vector3 nodePosition = new Vector3(); nodePosition.x = Utility.SymmetricRandom() * 750.0f; nodePosition.y = Utility.SymmetricRandom() * 100.0f + 25; nodePosition.z = Utility.SymmetricRandom() * 750.0f; // set the new position node.Position = nodePosition; // attach this node to the root node rootNode.AddChild( node ); // clone the knot string cloneName = string.Format( "Knot{0}", i ); clone = knot.Clone( cloneName ); // add the cloned knot to the scene node.AttachObject( clone ); } camera.Position = new Vector3( -50, 100, 500 ); camera.LookAt( new Vector3( 0, 0, 0 ) ); }
protected bool CalculateForDirectionalLight( Plane plane, Vector3[] vertices, out Vector2[] texCoors, out ColorEx[] colors ) { texCoors = new Vector2[ vertices.Length ]; colors = new ColorEx[ vertices.Length ]; float angle = Utility.Abs( plane.Normal.Dot( this.DerivedDirection ) ); ColorEx lightCol = new ColorEx( textureColor.a * angle, textureColor.r, textureColor.g, textureColor.b ); for ( int i = 0; i < vertices.Length; i++ ) { colors[ i ] = lightCol; } return true; }
/// <summary> /// /// </summary> /// <param name="plane"></param> /// <param name="curvature"></param> /// <param name="tiling"></param> /// <param name="distance"></param> /// <param name="orientation"></param> /// <param name="groupName"></param> /// <returns></returns> protected Mesh CreateSkyDomePlane( BoxPlane plane, float curvature, float tiling, float distance, Quaternion orientation, string groupName ) { Plane p = new Plane(); Vector3 up = Vector3.Zero; string meshName = "SkyDomePlane_"; // set up plane equation p.D = distance; switch ( plane ) { case BoxPlane.Front: p.Normal = Vector3.UnitZ; up = Vector3.UnitY; meshName += "Front"; break; case BoxPlane.Back: p.Normal = -Vector3.UnitZ; up = Vector3.UnitY; meshName += "Back"; break; case BoxPlane.Left: p.Normal = Vector3.UnitX; up = Vector3.UnitY; meshName += "Left"; break; case BoxPlane.Right: p.Normal = -Vector3.UnitX; up = Vector3.UnitY; meshName += "Right"; break; case BoxPlane.Up: p.Normal = -Vector3.UnitY; up = Vector3.UnitZ; meshName += "Up"; break; case BoxPlane.Down: return null; } // modify orientation p.Normal = orientation * p.Normal; up = orientation * up; // check to see if mesh exists MeshManager meshManager = MeshManager.Instance; Mesh planeMesh = (Mesh)meshManager[ meshName ]; // destroy existing if ( planeMesh != null ) { meshManager.Unload( planeMesh ); planeMesh.Dispose(); } // create new float planeSize = distance * 2; int segments = 16; planeMesh = meshManager.CreateCurvedIllusionPlane( meshName, groupName, p, planeSize, planeSize, curvature, segments, segments, false, 1, tiling, tiling, up, orientation, BufferUsage.DynamicWriteOnly, BufferUsage.StaticWriteOnly, true, true ); return planeMesh; }
/// <summary> /// Transforms a plane using the specified transform. /// </summary> /// <param name="matrix">Transformation matrix.</param> /// <param name="plane">Plane to transform.</param> /// <returns>A transformed plane.</returns> public static Plane Multiply( Matrix4 matrix, Plane plane ) { return matrix * plane; }
/// <summary> /// Overload. /// </summary> public virtual void SetSkyPlane( bool enable, Plane plane, string materialName ) { // call the overloaded method this.SetSkyPlane( enable, plane, materialName, 1000.0f, 10.0f, true, 0, ResourceGroupManager.DefaultResourceGroupName ); }
/// <summary> /// Used to multiply a transformation to a Plane. /// </summary> /// <param name="left"></param> /// <param name="plane"></param> /// <returns></returns> public static Plane operator *( Matrix4 left, Plane plane ) { Plane result = new Plane(); Vector3 planeNormal = plane.Normal; result.Normal = new Vector3( left.m00 * planeNormal.x + left.m01 * planeNormal.y + left.m02 * planeNormal.z, left.m10 * planeNormal.x + left.m11 * planeNormal.y + left.m12 * planeNormal.z, left.m20 * planeNormal.x + left.m21 * planeNormal.y + left.m22 * planeNormal.z ); Vector3 pt = planeNormal * -plane.D; pt = left * pt; result.D = -pt.Dot( result.Normal ); return result; }