private void GenerateTerrainGeometries() { SettingsContainer Settings = FileManager.MasteryFile.Settings; List <WorldFile> ActiveWorldFiles = FileManager.MasteryFile.ActiveWorldFiles; for (int i = 0; i < ActiveWorldFiles.Count; i++) { bool HasGeometry = false; for (int j = 0; j < TerrainGeometries.Count; j++) { if (ActiveWorldFiles[i] == TerrainGeometries[j].WorldFile) { HasGeometry = true; } } if (!HasGeometry) { Node3D Node = null; for (int j = 0; j < RenderNodeLayers.Count; j++) { if (RenderNodeLayers[j].Name.Replace("Layer:", "") == ActiveWorldFiles[i].LODID + "") { Node = RenderNodeLayers[j]; } } if (Node != null) { TerrainGeometryContainer NewContainer = new TerrainGeometryContainer(Render, Settings, ActiveWorldFiles[i]); //TerrainDeformableCoverContainer NewDeformedCover = new TerrainDeformableCoverContainer(Render,ActiveWorldFiles[i],NewContainer, Settings,FromBelowDepthTarget); TerrainWaterContainer WaterContainer = new TerrainWaterContainer( Render, NewContainer, ReflectionNode, RefractionNode, PropNode, ActiveWorldFiles[i], Settings, ActiveWorldFiles[i].GetPosition(), ReflectionRenderTarget, RefractionRenderTarget, DepthMapRenderTarget, FromBelowDepthTarget); DepthMapRenderTarget.DebugTextureName = "SceneWaterDepthDebug"; TerrainGeometries.Add(NewContainer); //DeformedTerrainGeometries.Add(NewDeformedCover); WaterGeometries.Add(WaterContainer); ReflectionNode.Attach(NewContainer.TerrainGeometry); RefractionNode.Attach(NewContainer.TerrainGeometry); Node.Attach(WaterContainer.Geom); //Node.Attach(NewDeformedCover.Geom); Node.Attach(NewContainer.TerrainGeometry); } } } }
public CollisionResults RayCastWater(Vector3 Origin, Vector3 Direction, float Range, bool HasCurrentChunkLock) { if (FileManager.MasteryFile == null) { return(new CollisionResults()); } int LOD = FileManager.CurrentWorldFile.LODID; SettingsContainer Settings = FileManager.MasteryFile.Settings; List <WorldFile> ActiveWorldFiles = FileManager.MasteryFile.ActiveWorldFiles; CollisionResults Results = new CollisionResults(); List <Vector2> QuadCheck = new List <Vector2>(); if (HasCurrentChunkLock) { if (FileManager.CurrentWorldFile != null) { float TerrainScale = FileManager.CurrentWorldFile.TerrainScale; float HeightScale = FileManager.CurrentWorldFile.HeightScale; int[,] HeightMap = FileManager.CurrentWorldFile.HeightMap; int[,] WaterHeightMap = FileManager.CurrentWorldFile.WaterHeightMap; float Precision = TerrainScale * 0.5f; for (float j = 0; j < Range; j += Precision) { Vector3 CurrentPosition = Origin + (Direction * j); Vector3 CurrentVertexPosition = (CurrentPosition - FileManager.CurrentWorldFile.GetPosition()) / TerrainScale; int VX = (int)Math.Floor(CurrentVertexPosition.X); int VY = (int)Math.Floor(CurrentVertexPosition.Y); if (VX < 0 || VY < 0 || VX >= HeightMap.GetLength(0) - 1 || VY >= HeightMap.GetLength(1) - 1) { continue; } float MidPoint = (HeightMap[VX, VY] + HeightMap[VX + 1, VY] + HeightMap[VX, VY + 1] + HeightMap[VX + 1, VY + 1] + WaterHeightMap[VX, VY] + WaterHeightMap[VX + 1, VY] + WaterHeightMap[VX, VY + 1] + WaterHeightMap[VX + 1, VY + 1]) / 4; Vector3[] QuadVertices = { new Vector3(0, 0, (WaterHeightMap[VX, VY] + HeightMap[VX, VY]) * HeightScale), new Vector3(TerrainScale, 0, (WaterHeightMap[VX + 1, VY] + HeightMap[VX + 1, VY]) * HeightScale), new Vector3(0, TerrainScale, (WaterHeightMap[VX, VY + 1] + HeightMap[VX, VY + 1]) * HeightScale), new Vector3(TerrainScale, TerrainScale, (WaterHeightMap[VX + 1, VY + 1] + HeightMap[VX + 1, VY + 1]) * HeightScale) }; if (!QuadCheck.Contains(new Vector2(VX, VY))) { QuadCheck.Add(new Vector2(VX, VY)); Vector3 VertexWorldPosition = FileManager.CurrentWorldFile.GetPosition() + new Vector3(VX * TerrainScale, VY * TerrainScale, 0); for (int k = 0; k < Indices.Length; k += 3) { Vector3 V0 = VertexWorldPosition + QuadVertices[Indices[k]]; Vector3 V1 = VertexWorldPosition + QuadVertices[Indices[k + 1]]; Vector3 V2 = VertexWorldPosition + QuadVertices[Indices[k + 2]]; if (CollisionUtil.Intersect(V0, V1, V2, Origin, Direction)) { TerrainWaterContainer WaterGeom = WaterGeometries.Where(x => x.WorldFile.FileName == FileManager.CurrentWorldFile.FileName).First(); Vector3 CollisionPoint = CollisionUtil.GetCollisionPoint(V0, V1, V2, Origin, Direction); CollisionResult Result = new CollisionResult( V0, V1, V2, Origin, CollisionPoint, WaterGeom.Geom); Results.Add(Result); } } } } } } else { int PX = (int)Math.Floor(Origin.X / Settings.ChunkSize); int PY = (int)Math.Floor(Origin.Y / Settings.ChunkSize); for (int i = 0; i < ActiveWorldFiles.Count; i++) { int ValidLOD = LOD == -1 ? ActiveWorldFiles[i].LODID : LOD; if (Math.Abs(ActiveWorldFiles[i].IDX - PX) <= Settings.ChunkSelectionRadius && Math.Abs(ActiveWorldFiles[i].IDY - PY) < Settings.ChunkSelectionRadius && ActiveWorldFiles[i].LODID == ValidLOD) { float TerrainScale = ActiveWorldFiles[i].TerrainScale; float HeightScale = ActiveWorldFiles[i].HeightScale; int[,] HeightMap = ActiveWorldFiles[i].HeightMap; int[,] WaterHeightMap = FileManager.CurrentWorldFile.WaterHeightMap; float Precision = TerrainScale * 0.5f; for (float j = 0; j < Range; j += Precision) { Vector3 CurrentPosition = Origin + (Direction * j); Vector3 CurrentVertexPosition = (CurrentPosition - ActiveWorldFiles[i].GetPosition()) / TerrainScale; int VX = (int)Math.Floor(CurrentVertexPosition.X); int VY = (int)Math.Floor(CurrentVertexPosition.Y); if (VX < 0 || VY < 0 || VX >= HeightMap.GetLength(0) - 1 || VY >= HeightMap.GetLength(1) - 1) { continue; } float MidPoint = (HeightMap[VX, VY] + HeightMap[VX + 1, VY] + HeightMap[VX, VY + 1] + HeightMap[VX + 1, VY + 1] + WaterHeightMap[VX, VY] + WaterHeightMap[VX + 1, VY] + WaterHeightMap[VX, VY + 1] + WaterHeightMap[VX + 1, VY + 1]) / 4; Vector3[] QuadVertices = { new Vector3(0, 0, (WaterHeightMap[VX, VY] + HeightMap[VX, VY]) * HeightScale), new Vector3(TerrainScale, 0, (WaterHeightMap[VX + 1, VY] + HeightMap[VX + 1, VY]) * HeightScale), new Vector3(0, TerrainScale, (WaterHeightMap[VX, VY + 1] + HeightMap[VX, VY + 1]) * HeightScale), new Vector3(TerrainScale, TerrainScale, (WaterHeightMap[VX + 1, VY + 1] + HeightMap[VX + 1, VY + 1]) * HeightScale) }; if (!QuadCheck.Contains(new Vector2(VX, VY))) { QuadCheck.Add(new Vector2(VX, VY)); Vector3 VertexWorldPosition = ActiveWorldFiles[i].GetPosition() + new Vector3(VX * TerrainScale, VY * TerrainScale, 0); for (int k = 0; k < Indices.Length; k += 3) { Vector3 V0 = VertexWorldPosition + QuadVertices[Indices[k]]; Vector3 V1 = VertexWorldPosition + QuadVertices[Indices[k + 1]]; Vector3 V2 = VertexWorldPosition + QuadVertices[Indices[k + 2]]; if (CollisionUtil.Intersect(V0, V1, V2, Origin, Direction)) { Vector3 CollisionPoint = CollisionUtil.GetCollisionPoint(V0, V1, V2, Origin, Direction); TerrainWaterContainer WaterGeom = WaterGeometries.Where(x => x.WorldFile.FileName == FileManager.CurrentWorldFile.FileName).First(); CollisionResult Result = new CollisionResult( V0, V1, V2, Origin, CollisionPoint, WaterGeom.Geom); Results.Add(Result); } } } } } } } return(Results); }