protected override void SetupContent() { SceneManager.SetSkyBox( true, "Examples/StormySkyBox", 5000 ); // add a skybox // setup some basic lighting for our scene SceneManager.AmbientLight = new ColorEx( 0.5f, 0.5f, 0.5f ); SceneManager.CreateLight( "DynTexLight1" ).Position = new Vector3( 20, 80, 50 ); // set initial camera position CameraManager.setStyle( CameraStyle.Manual ); Camera.Position = new Vector3( 0, 0, 200 ); TrayManager.ShowCursor(); // create our dynamic texture with 8-bit luminance texels var tex = TextureManager.Instance.CreateManual( "thaw", ResourceGroupManager.DefaultResourceGroupName, TextureType.TwoD, TEXTURE_SIZE, TEXTURE_SIZE, 0, PixelFormat.L8, TextureUsage.DynamicWriteOnly ); this.mTexBuf = tex.GetBuffer(); // save off the texture buffer // initialise the texture to have full luminance this.mTexBuf.Lock( BufferLocking.Discard ); Memory.Set( this.mTexBuf.CurrentLock.Data, 0xff, this.mTexBuf.Size ); this.mTexBuf.Unlock(); // create a penguin and attach him to our penguin node var penguin = SceneManager.CreateEntity( "Penguin", "penguin.mesh" ); this.mPenguinNode = SceneManager.RootSceneNode.CreateChildSceneNode(); this.mPenguinNode.AttachObject( penguin ); // get and enable the penguin idle animation this.mPenguinAnimState = penguin.GetAnimationState( "amuse" ); this.mPenguinAnimState.IsEnabled = true; // create a snowstorm over the scene, and fast forward it a little var ps = ParticleSystemManager.Instance.CreateSystem( "Snow", "Examples/Snow" ); SceneManager.RootSceneNode.AttachObject( ps ); ps.FastForward( 30 ); // create a frosted screen in front of the camera, using our dynamic texture to "thaw" certain areas var ent = SceneManager.CreateEntity( "Plane", PrefabEntity.Plane ); ent.MaterialName = "Examples/Frost"; var node = SceneManager.RootSceneNode.CreateChildSceneNode(); node.Position = new Vector3( 0, 0, 50 ); node.AttachObject( ent ); this.mPlaneSize = ent.BoundingBox.Size.x; // remember the size of the plane this.mCursorQuery = SceneManager.CreateRayQuery( new Ray() ); // create a ray scene query for the cursor this.mTimeSinceLastFreeze = 0; this.mWiping = false; }
public override void CreateScene() { // Set ambient light scene.AmbientLight = new ColorEx( 0.25f, 0.25f, 0.25f ); // Create a skybox scene.SetSkyBox( true, "Examples/CloudyNoonSkyBox", 500 ); // put the skybox node in the default zone ( (PCZSceneManager)scene ).SetSkyZone( null ); // Create a light Light l = scene.CreateLight( "MainLight" ); l.Position = new Vector3( 0, 0, 0 ); l.SetAttenuation( 500, 0.5f, 1.0f, 0.0f ); // Accept default settings: point light, white diffuse, just set position // attach light to a scene node so the PCZSM can handle it properly (zone-wise) // IMPORTANT: Lights (just like cameras) MUST be connected to a scene node! SceneNode lightNode = mCameraNode.CreateChildSceneNode( "light_Node" ); lightNode.AttachObject( l ); // Fog // NB it's VERY important to set this before calling setWorldGeometry // because the vertex program picked will be different ColorEx fadeColour = new ColorEx( 0.101f, 0.125f, 0.1836f ); scene.SetFog( FogMode.Linear, fadeColour, .001f, 500, 1000 ); window.GetViewport( 0 ).BackgroundColor = fadeColour; // create a terrain zone string terrain_cfg = "Terrain.xml"; string zoneName = "Terrain1_Zone"; PCZone terrainZone = createTerrainZone( zoneName, terrain_cfg ); /* // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain2_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move second terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(1500, 0, 0); // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain3_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(0, 0, 1500); // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain4_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(-1500, 0, 0); // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain5_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(0, 0, -1500); // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain6_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(1500, 0, 1500); // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain7_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(-1500, 0, -1500); // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain8_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(-1500, 0, 1500); // Create another terrain zone terrain_cfg = "terrain.cfg"; zoneName = "Terrain9_Zone"; terrainZone = createTerrainZone(zoneName, terrain_cfg); // move terrain next to first terrain terrainZone->getEnclosureNode()->setPosition(1500, 0, -1500); */ // set far clip plane to one terrain zone width (we have a LOT of terrain here, so we need to do far clipping!) camera.Far = 1500; // create test buildinig RoomObject roomObj = new RoomObject(); buildingNode = roomObj.createTestBuilding( scene, "1" ); buildingNode.Position = new Vector3( 500, 165, 570 ); //Ogre::Radian r = Radian(3.1416/7.0); //buildingNode->rotate(Vector3::UNIT_Y, r); // create another test buildinig RoomObject roomObj2 = new RoomObject(); buildingNode = roomObj2.createTestBuilding( scene, "2" ); buildingNode.Position = new Vector3( 400, 165, 570 ); //Ogre::Radian r = Radian(3.1416/7.0); //buildingNode->rotate(Vector3::UNIT_Y, r); // Position camera in the center of the building mCameraNode.Position = buildingNode.Position; // Look back along -Z camera.LookAt( mCameraNode.DerivedPosition + new Vector3( 0, 0, -300 ) ); // Update bounds for camera //mCameraNode.->_updateBounds(); // create the ray scene query raySceneQuery = scene.CreateRayQuery( new Ray( camera.ParentNode.Position, Vector3.NegativeUnitZ ) ); raySceneQuery.SortByDistance = true; }
protected override void SetupContent() { //Setup default effects values. this.curLightingModel = ShaderSystemLightingModel.PerVertexLighting; this.perPixelFogEnable = false; this.specularEnable = false; this.reflectionMapEnable = false; this.reflectionMapSubRS = null; this.layerBlendSubRS = null; this.rayQuery = SceneManager.CreateRayQuery( new Ray() ); this.targetObj = null; //Set ambient SceneManager.AmbientLight = new ColorEx( 0.2f, 0.2f, 0.2f ); SceneManager.SetSkyBox( true, "Examples/SceneCubeMap2", 10000 ); MeshManager.Instance.CreatePlane( "Myplane", ResourceGroupManager.DefaultResourceGroupName, new Plane( Vector3.UnitY, 0 ), 1500, 1500, 25, 25, true, 1, 60, 60, Vector3.UnitZ ); Entity planeEnt = SceneManager.CreateEntity( "plane", "Myplane" ); planeEnt.MaterialName = "Examples/Rockwall"; planeEnt.CastShadows = false; SceneManager.RootSceneNode.CreateChildSceneNode( Vector3.Zero ).AttachObject( planeEnt ); //Load sample meshes an generate tangent vectors. for ( int i = 0; i < this.meshArray.Length; i++ ) { string curMeshName = this.meshArray[ i ]; Mesh mesh = MeshManager.Instance.Load( curMeshName, ResourceGroupManager.DefaultResourceGroupName, BufferUsage.DynamicWriteOnly, BufferUsage.StaticWriteOnly ); //Build tangent vectors, all our meshes use only 1 texture coordset //Note we can build into ves_tangent now (sm2+) short src, dst; if ( !mesh.SuggestTangentVectorBuildParams( out src, out dst ) ) { mesh.BuildTangentVectors( src, dst ); } } Entity entity; SceneNode childNode; //Create the main entity and mark it as the current target object entity = SceneManager.CreateEntity( MainEntityName, MainEntityMesh ); this.targetEntities.Add( entity ); childNode = SceneManager.RootSceneNode.CreateChildSceneNode(); childNode.AttachObject( entity ); this.targetObj = entity; childNode.ShowBoundingBox = true; //Create reflection entity that will show the exported material. string mainExportedMaterial = SceneManager.GetEntity( MainEntityName ).GetSubEntity( 0 ).MaterialName + "_RTSS_Export"; var matMainEnt = (Material)MaterialManager.Instance.GetByName( mainExportedMaterial ); entity = SceneManager.CreateEntity( "ExportedMaterialEntity", MainEntityMesh ); entity.GetSubEntity( 0 ).Material = matMainEnt; childNode = SceneManager.RootSceneNode.CreateChildSceneNode(); childNode.Position = new Vector3( 0, 200, -200 ); childNode.AttachObject( entity ); //Create texture layer blending demonstration entity this.layeredBlendingEntity = SceneManager.CreateEntity( "LayeredBlendingMaterialEntity", MainEntityMesh ); this.layeredBlendingEntity.MaterialName = "RTSS/LayeredBlending"; this.layeredBlendingEntity.GetSubEntity( 0 ).SetCustomParameter( 2, Vector4.Zero ); childNode = SceneManager.RootSceneNode.CreateChildSceneNode(); childNode.Position = new Vector3( 300, 200, -200 ); childNode.AttachObject( this.layeredBlendingEntity ); //Grab the render state of the material RenderState renderState = ShaderGenerator.Instance.GetRenderState( ShaderGenerator.DefaultSchemeName, "RTSS/LayeredBlending", 0 ); if ( renderState != null ) { var subRenderStateList = renderState.TemplateSubRenderStateList; for ( int i = 0; i < subRenderStateList.Count; i++ ) { SubRenderState curSubRenderState = subRenderStateList[ i ]; if ( curSubRenderState.Type == FFPTexturing.FFPType ) { this.layerBlendSubRS = curSubRenderState as LayeredBlending; break; } } } //Create per pixel lighting demo entity entity = SceneManager.CreateEntity( "PerPixelEntity", "knot.mesh" ); entity.MaterialName = "RTSS/PerPixel_SinglePass"; childNode = SceneManager.RootSceneNode.CreateChildSceneNode(); childNode.Position = new Vector3( 300, 100, -100 ); childNode.AttachObject( entity ); //Create normal map lighting demo entity entity = SceneManager.CreateEntity( "NormalMapEntity", "knot.mesh" ); entity.MaterialName = "RTSS/NormalMapping_SinglePass"; childNode = SceneManager.RootSceneNode.CreateChildSceneNode(); childNode.Position = new Vector3( -300, 100, -100 ); childNode.AttachObject( entity ); //OpenGL ES 2.0 does not support texture atlases if ( !Root.Instance.RenderSystem.Name.Contains( "OpenGL ES 2" ) ) { RenderState mainRenderState = ShaderGenerator.Instance.CreateOrRetrieveRenderState( ShaderGenerator.DefaultSchemeName ).Item1; mainRenderState.AddTemplateSubRenderState( ShaderGenerator.Instance.CreateSubRenderState( TextureAtlasSampler.SGXType ) ); //Create texture atlas object and node ManualObject atlasObject = CreateTextureAtlasObject(); childNode = SceneManager.RootSceneNode.CreateChildSceneNode(); childNode.AttachObject( atlasObject ); } CreateDirectionalLight(); CreatePointLight(); CreateSpotLight(); RenderState schemeRenderState = ShaderGenerator.Instance.GetRenderState( ShaderGenerator.DefaultSchemeName ); //take responsibility for updating the light count manually schemeRenderState.LightCountAutoUpdate = false; SetupUI(); Camera.Position = new Vector3( 0, 300, 450 ); Viewport.MaterialScheme = ShaderGenerator.DefaultSchemeName; //Mark system as on DetailsPanel.SetParamValue( 11, "On" ); // a friendly reminder var names = new List<string>(); names.Add( "Help" ); TrayManager.CreateParamsPanel( TrayLocation.TopLeft, "Help", 100, names ).SetParamValue( 0, "H/F1" ); UpdateSystemShaders(); }
protected override void OnFrameStarted(object source, FrameEventArgs e) { frameCount++; int tick = Environment.TickCount; time += e.TimeSinceLastFrame; float moveTime = e.TimeSinceLastFrame; if (moveTime > 1) { moveTime = 1; } Axiom.SceneManagers.Multiverse.WorldManager.Instance.Time = time; if ((tick - lastTick) > 100) { Console.WriteLine("long frame: {0}", tick - lastTick); LogManager.Instance.Write("long frame: {0}", tick - lastTick); } lastTick = tick; // int hpg = gen.HeightPointsGenerated; // if ( lastHeightPointsGenerated != hpg ) // { // Console.WriteLine("HeightPointsGenerated: {0}", hpg - lastHeightPointsGenerated); // lastHeightPointsGenerated = hpg; // } float scaleMove = 20 * oneMeter * moveTime; // reset acceleration zero camAccel = Vector3.Zero; // set the scaling of camera motion cameraScale = 100 * moveTime; bool retry = true; //System.Threading.Thread.Sleep(3000); //while (retry) //{ // // TODO: Move this into an event queueing mechanism that is processed every frame // try // { // input.Capture(); // retry = false; // } // catch (Exception ex) // { // System.Threading.Thread.Sleep(1000); // } //} // TODO: Move this into an event queueing mechanism that is processed every frame bool realIsActive = window.IsActive; try { // force a reset of axiom's internal input state so that it will call Acquire() on the // input device again. if (captureFailed) { window.IsActive = false; input.Capture(); window.IsActive = realIsActive; } input.Capture(); captureFailed = false; } catch (Exception ex) { Console.WriteLine(ex.Message); captureFailed = true; System.Threading.Thread.Sleep(1000); } finally { window.IsActive = realIsActive; } if (input.IsKeyPressed(KeyCodes.Escape)) { Root.Instance.QueueEndRendering(); return; } if (input.IsKeyPressed(KeyCodes.A)) { camAccel.x = -0.5f; } if (input.IsKeyPressed(KeyCodes.D)) { camAccel.x = 0.5f; } if (input.IsKeyPressed(KeyCodes.W)) { camAccel.z = -1.0f; } if (input.IsKeyPressed(KeyCodes.S)) { camAccel.z = 1.0f; } if (!captureFailed) { camAccel.y += (float)(input.RelativeMouseZ * 0.1f); } if (input.IsKeyPressed(KeyCodes.Left)) { camera.Yaw(cameraScale); } if (input.IsKeyPressed(KeyCodes.Right)) { camera.Yaw(-cameraScale); } if (input.IsKeyPressed(KeyCodes.Up)) { camera.Pitch(cameraScale); } if (input.IsKeyPressed(KeyCodes.Down)) { camera.Pitch(-cameraScale); } // subtract the time since last frame to delay specific key presses toggleDelay -= e.TimeSinceLastFrame; // toggle rendering mode if (input.IsKeyPressed(KeyCodes.R) && toggleDelay < 0) { if (camera.SceneDetail == SceneDetailLevel.Points) { camera.SceneDetail = SceneDetailLevel.Solid; } else if (camera.SceneDetail == SceneDetailLevel.Solid) { camera.SceneDetail = SceneDetailLevel.Wireframe; } else { camera.SceneDetail = SceneDetailLevel.Points; } Console.WriteLine("Rendering mode changed to '{0}'.", camera.SceneDetail); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F) && toggleDelay < 0) { followTerrain = !followTerrain; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.H) && toggleDelay < 0) { humanSpeed = !humanSpeed; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.T) && toggleDelay < 0) { // toggle the texture settings switch (filtering) { case TextureFiltering.Bilinear: filtering = TextureFiltering.Trilinear; aniso = 1; break; case TextureFiltering.Trilinear: filtering = TextureFiltering.Anisotropic; aniso = 8; break; case TextureFiltering.Anisotropic: filtering = TextureFiltering.Bilinear; aniso = 1; break; } Console.WriteLine("Texture Filtering changed to '{0}'.", filtering); // set the new default MaterialManager.Instance.SetDefaultTextureFiltering(filtering); MaterialManager.Instance.DefaultAnisotropy = aniso; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.P)) { string[] temp = Directory.GetFiles(Environment.CurrentDirectory, "screenshot*.jpg"); string fileName = string.Format("screenshot{0}.jpg", temp.Length + 1); // show briefly on the screen window.DebugText = string.Format("Wrote screenshot '{0}'.", fileName); TakeScreenshot(fileName); // show for 2 seconds debugTextDelay = 2.0f; } if (input.IsKeyPressed(KeyCodes.B)) { scene.ShowBoundingBoxes = !scene.ShowBoundingBoxes; } if (input.IsKeyPressed(KeyCodes.O)) { // hide all overlays, includes ones besides the debug overlay viewport.OverlaysEnabled = !viewport.OverlaysEnabled; } if (input.IsKeyPressed(KeyCodes.F1) && toggleDelay < 0) { Axiom.SceneManagers.Multiverse.WorldManager.Instance.DrawStitches = !Axiom.SceneManagers.Multiverse.WorldManager.Instance.DrawStitches; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F2) && toggleDelay < 0) { Axiom.SceneManagers.Multiverse.WorldManager.Instance.DrawTiles = !Axiom.SceneManagers.Multiverse.WorldManager.Instance.DrawTiles; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F3) && toggleDelay < 0) { Console.WriteLine("Camera Location: {0}, {1}, {2}", camera.Position.x.ToString("F3"), camera.Position.y.ToString("F3"), camera.Position.z.ToString("F3")); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F4) && toggleDelay < 0) { preview = !preview; if (preview) { // when in preview mode, move the camera up high and look at the ground camera.MoveRelative(new Vector3(0, 1000 * oneMeter, 0)); camera.LookAt(new Vector3(0, 0, 0)); followTerrain = false; } else { // when not in preview mode, hug the ground followTerrain = true; } SetupScene(); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F5) && toggleDelay < 0) { if (WorldManager.Instance.OceanWaveHeight >= 500) { WorldManager.Instance.OceanWaveHeight -= 500; } toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F6) && toggleDelay < 0) { WorldManager.Instance.OceanWaveHeight += 500; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F7) && toggleDelay < 0) { NewRoad(); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F8) && toggleDelay < 0) { WorldManager.Instance.SeaLevel += 500; toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F9) && toggleDelay < 0) { StreamWriter s = new StreamWriter("boundaries.xml"); XmlTextWriter w = new XmlTextWriter(s); //w.Formatting = Formatting.Indented; //w.Indentation = 2; //w.IndentChar = ' '; mvScene.ExportBoundaries(w); w.Close(); s.Close(); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F10) && toggleDelay < 0) { StreamReader s = new StreamReader("boundaries.xml"); XmlTextReader r = new XmlTextReader(s); mvScene.ImportBoundaries(r); r.Close(); s.Close(); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F11) && toggleDelay < 0) { StreamWriter s = new StreamWriter("terrain.xml"); gen.ToXML(s); s.Close(); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.F12) && toggleDelay < 0) { StreamReader s = new StreamReader("terrain.xml"); gen.FromXML(s); s.Close(); SetupScene(); toggleDelay = 1; } if (input.IsKeyPressed(KeyCodes.I)) { //point camera north camera.Direction = Vector3.NegativeUnitZ; } if (input.IsKeyPressed(KeyCodes.K)) { //point camera south camera.Direction = Vector3.UnitZ; } if (input.IsKeyPressed(KeyCodes.J)) { //point camera west camera.Direction = Vector3.NegativeUnitX; } if (input.IsKeyPressed(KeyCodes.L)) { //point camera east camera.Direction = Vector3.UnitX; } if (!captureFailed) { if (!input.IsMousePressed(MouseButtons.Left)) { float cameraYaw = -input.RelativeMouseX * .13f; float cameraPitch = -input.RelativeMouseY * .13f; camera.Yaw(cameraYaw); camera.Pitch(cameraPitch); } else { cameraVector.x += input.RelativeMouseX * 0.13f; } } if (humanSpeed) { // in game running speed is 7m/sec //camVelocity = camAccel * 7 * oneMeter; camVelocity = camAccel * 32 * oneMeter; } else { camVelocity += (camAccel * scaleMove * camSpeed); } // Console.WriteLine("ScameMove: {0}", scaleMove.ToString("F3")); // Console.WriteLine("Camera Accel: {0}, {1}, {2}", camAccel.x.ToString("F3"), //camAccel.y.ToString("F3"), camAccel.z.ToString("F3")); // Console.WriteLine("Camera Velocity: {0}, {1}, {2}", camVelocity.x.ToString("F3"), //camVelocity.y.ToString("F3"), camVelocity.z.ToString("F3")); // move the camera based on the accumulated movement vector camera.MoveRelative(camVelocity * moveTime); // Now dampen the Velocity - only if user is not accelerating if (camAccel == Vector3.Zero) { float slowDown = 6 * moveTime; if (slowDown > 1) { slowDown = 1; } camVelocity *= (1 - slowDown); } if (followTerrain) { // adjust new camera position to be a fixed distance above the ground Axiom.Core.RaySceneQuery raySceneQuery = scene.CreateRayQuery(new Ray(camera.Position, Vector3.NegativeUnitY)); raySceneQuery.QueryMask = (ulong)Axiom.SceneManagers.Multiverse.RaySceneQueryType.Height; ArrayList results = raySceneQuery.Execute(); RaySceneQueryResultEntry result = (RaySceneQueryResultEntry)results[0]; camera.Position = new Vector3(camera.Position.x, result.worldFragment.SingleIntersection.y + (2f * oneMeter), camera.Position.z); } // update performance stats once per second if (statDelay < 0.0f && showDebugOverlay) { UpdateStats(); statDelay = 1.0f; } else { statDelay -= e.TimeSinceLastFrame; } // turn off debug text when delay ends if (debugTextDelay < 0.0f) { debugTextDelay = 0.0f; window.DebugText = ""; } else if (debugTextDelay > 0.0f) { debugTextDelay -= e.TimeSinceLastFrame; } }
protected override void CreateScene() { viewport.BackgroundColor = ColorEx.White; scene.AmbientLight = new ColorEx(0.5f, 0.5f, 0.5f); Light light = scene.CreateLight("MainLight"); light.Position = new Vector3(20, 80, 50); light.Diffuse = ColorEx.Blue; scene.LoadWorldGeometry("landscape.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", 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)); raySceneQuery = scene.CreateRayQuery( new Ray(camera.Position, Vector3.NegativeUnitY)); }