aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs340
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs568
2 files changed, 454 insertions, 454 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
index e9fd0cb..8fc36d1 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs
@@ -1,170 +1,170 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD 9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Text; 29using System.Text;
30 30
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.Framework; 32using OpenSim.Region.Framework;
33using OpenSim.Region.CoreModules; 33using OpenSim.Region.CoreModules;
34using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
35 35
36using Nini.Config; 36using Nini.Config;
37using log4net; 37using log4net;
38 38
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41namespace OpenSim.Region.Physics.BulletSPlugin 41namespace OpenSim.Region.Physics.BulletSPlugin
42{ 42{
43public sealed class BSTerrainHeightmap : BSTerrainPhys 43public sealed class BSTerrainHeightmap : BSTerrainPhys
44{ 44{
45 static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; 45 static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]";
46 46
47 BulletHeightMapInfo m_mapInfo = null; 47 BulletHeightMapInfo m_mapInfo = null;
48 48
49 // Constructor to build a default, flat heightmap terrain. 49 // Constructor to build a default, flat heightmap terrain.
50 public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) 50 public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
51 : base(physicsScene, regionBase, id) 51 : base(physicsScene, regionBase, id)
52 { 52 {
53 Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); 53 Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE);
54 Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); 54 Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION);
55 int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; 55 int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
56 float[] initialMap = new float[totalHeights]; 56 float[] initialMap = new float[totalHeights];
57 for (int ii = 0; ii < totalHeights; ii++) 57 for (int ii = 0; ii < totalHeights; ii++)
58 { 58 {
59 initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; 59 initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION;
60 } 60 }
61 m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); 61 m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero);
62 m_mapInfo.minCoords = minTerrainCoords; 62 m_mapInfo.minCoords = minTerrainCoords;
63 m_mapInfo.maxCoords = maxTerrainCoords; 63 m_mapInfo.maxCoords = maxTerrainCoords;
64 m_mapInfo.terrainRegionBase = TerrainBase; 64 m_mapInfo.terrainRegionBase = TerrainBase;
65 // Don't have to free any previous since we just got here. 65 // Don't have to free any previous since we just got here.
66 BuildHeightmapTerrain(); 66 BuildHeightmapTerrain();
67 } 67 }
68 68
69 // This minCoords and maxCoords passed in give the size of the terrain (min and max Z 69 // This minCoords and maxCoords passed in give the size of the terrain (min and max Z
70 // are the high and low points of the heightmap). 70 // are the high and low points of the heightmap).
71 public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, 71 public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
72 Vector3 minCoords, Vector3 maxCoords) 72 Vector3 minCoords, Vector3 maxCoords)
73 : base(physicsScene, regionBase, id) 73 : base(physicsScene, regionBase, id)
74 { 74 {
75 m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); 75 m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero);
76 m_mapInfo.minCoords = minCoords; 76 m_mapInfo.minCoords = minCoords;
77 m_mapInfo.maxCoords = maxCoords; 77 m_mapInfo.maxCoords = maxCoords;
78 m_mapInfo.minZ = minCoords.Z; 78 m_mapInfo.minZ = minCoords.Z;
79 m_mapInfo.maxZ = maxCoords.Z; 79 m_mapInfo.maxZ = maxCoords.Z;
80 m_mapInfo.terrainRegionBase = TerrainBase; 80 m_mapInfo.terrainRegionBase = TerrainBase;
81 81
82 // Don't have to free any previous since we just got here. 82 // Don't have to free any previous since we just got here.
83 BuildHeightmapTerrain(); 83 BuildHeightmapTerrain();
84 } 84 }
85 85
86 public override void Dispose() 86 public override void Dispose()
87 { 87 {
88 ReleaseHeightMapTerrain(); 88 ReleaseHeightMapTerrain();
89 } 89 }
90 90
91 // Using the information in m_mapInfo, create the physical representation of the heightmap. 91 // Using the information in m_mapInfo, create the physical representation of the heightmap.
92 private void BuildHeightmapTerrain() 92 private void BuildHeightmapTerrain()
93 { 93 {
94 m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, 94 m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
95 m_mapInfo.minCoords, m_mapInfo.maxCoords, 95 m_mapInfo.minCoords, m_mapInfo.maxCoords,
96 m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); 96 m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN);
97 97
98 // Create the terrain shape from the mapInfo 98 // Create the terrain shape from the mapInfo
99 m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), 99 m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
100 PhysicsShapeType.SHAPE_TERRAIN); 100 PhysicsShapeType.SHAPE_TERRAIN);
101 101
102 // The terrain object initial position is at the center of the object 102 // The terrain object initial position is at the center of the object
103 Vector3 centerPos; 103 Vector3 centerPos;
104 centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); 104 centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f);
105 centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); 105 centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
106 centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f); 106 centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f);
107 107
108 m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, 108 m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID,
109 BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, 109 BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr,
110 m_mapInfo.ID, centerPos, Quaternion.Identity)); 110 m_mapInfo.ID, centerPos, Quaternion.Identity));
111 111
112 // Set current terrain attributes 112 // Set current terrain attributes
113 BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); 113 BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction);
114 BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); 114 BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction);
115 BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); 115 BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution);
116 BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 116 BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
117 117
118 // Return the new terrain to the world of physical objects 118 // Return the new terrain to the world of physical objects
119 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); 119 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
120 120
121 // redo its bounding box now that it is in the world 121 // redo its bounding box now that it is in the world
122 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); 122 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
123 123
124 BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr, 124 BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr,
125 (uint)CollisionFilterGroups.TerrainFilter, 125 (uint)CollisionFilterGroups.TerrainFilter,
126 (uint)CollisionFilterGroups.TerrainMask); 126 (uint)CollisionFilterGroups.TerrainMask);
127 127
128 // Make it so the terrain will not move or be considered for movement. 128 // Make it so the terrain will not move or be considered for movement.
129 BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); 129 BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
130 130
131 return; 131 return;
132 } 132 }
133 133
134 // If there is information in m_mapInfo pointing to physical structures, release same. 134 // If there is information in m_mapInfo pointing to physical structures, release same.
135 private void ReleaseHeightMapTerrain() 135 private void ReleaseHeightMapTerrain()
136 { 136 {
137 if (m_mapInfo != null) 137 if (m_mapInfo != null)
138 { 138 {
139 if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) 139 if (m_mapInfo.terrainBody.ptr != IntPtr.Zero)
140 { 140 {
141 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); 141 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
142 // Frees both the body and the shape. 142 // Frees both the body and the shape.
143 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); 143 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
144 BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); 144 BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr);
145 } 145 }
146 } 146 }
147 m_mapInfo = null; 147 m_mapInfo = null;
148 } 148 }
149 149
150 // The passed position is relative to the base of the region. 150 // The passed position is relative to the base of the region.
151 public override float GetHeightAtXYZ(Vector3 pos) 151 public override float GetHeightAtXYZ(Vector3 pos)
152 { 152 {
153 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 153 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
154 154
155 int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; 155 int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X;
156 try 156 try
157 { 157 {
158 ret = m_mapInfo.heightMap[mapIndex]; 158 ret = m_mapInfo.heightMap[mapIndex];
159 } 159 }
160 catch 160 catch
161 { 161 {
162 // Sometimes they give us wonky values of X and Y. Give a warning and return something. 162 // Sometimes they give us wonky values of X and Y. Give a warning and return something.
163 PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", 163 PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
164 LogHeader, m_mapInfo.terrainRegionBase, pos); 164 LogHeader, m_mapInfo.terrainRegionBase, pos);
165 ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 165 ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
166 } 166 }
167 return ret; 167 return ret;
168 } 168 }
169} 169}
170} 170}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
index bbb014a..a199078 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs
@@ -1,284 +1,284 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD 9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Text; 29using System.Text;
30 30
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.Framework; 32using OpenSim.Region.Framework;
33using OpenSim.Region.CoreModules; 33using OpenSim.Region.CoreModules;
34using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
35 35
36using Nini.Config; 36using Nini.Config;
37using log4net; 37using log4net;
38 38
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41namespace OpenSim.Region.Physics.BulletSPlugin 41namespace OpenSim.Region.Physics.BulletSPlugin
42{ 42{
43public sealed class BSTerrainMesh : BSTerrainPhys 43public sealed class BSTerrainMesh : BSTerrainPhys
44{ 44{
45 static string LogHeader = "[BULLETSIM TERRAIN MESH]"; 45 static string LogHeader = "[BULLETSIM TERRAIN MESH]";
46 46
47 private float[] m_savedHeightMap; 47 private float[] m_savedHeightMap;
48 int m_sizeX; 48 int m_sizeX;
49 int m_sizeY; 49 int m_sizeY;
50 50
51 BulletShape m_terrainShape; 51 BulletShape m_terrainShape;
52 BulletBody m_terrainBody; 52 BulletBody m_terrainBody;
53 53
54 public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) 54 public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
55 : base(physicsScene, regionBase, id) 55 : base(physicsScene, regionBase, id)
56 { 56 {
57 } 57 }
58 58
59 public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) 59 public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */)
60 : base(physicsScene, regionBase, id) 60 : base(physicsScene, regionBase, id)
61 { 61 {
62 } 62 }
63 63
64 // Create terrain mesh from a heightmap. 64 // Create terrain mesh from a heightmap.
65 public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, 65 public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
66 Vector3 minCoords, Vector3 maxCoords) 66 Vector3 minCoords, Vector3 maxCoords)
67 : base(physicsScene, regionBase, id) 67 : base(physicsScene, regionBase, id)
68 { 68 {
69 int indicesCount; 69 int indicesCount;
70 int[] indices; 70 int[] indices;
71 int verticesCount; 71 int verticesCount;
72 float[] vertices; 72 float[] vertices;
73 73
74 m_savedHeightMap = initialMap; 74 m_savedHeightMap = initialMap;
75 75
76 m_sizeX = (int)(maxCoords.X - minCoords.X); 76 m_sizeX = (int)(maxCoords.X - minCoords.X);
77 m_sizeY = (int)(maxCoords.Y - minCoords.Y); 77 m_sizeY = (int)(maxCoords.Y - minCoords.Y);
78 78
79 if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, 79 if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY,
80 (float)m_sizeX, (float)m_sizeY, 80 (float)m_sizeX, (float)m_sizeY,
81 Vector3.Zero, 1.0f, 81 Vector3.Zero, 1.0f,
82 out indicesCount, out indices, out verticesCount, out vertices)) 82 out indicesCount, out indices, out verticesCount, out vertices))
83 { 83 {
84 // DISASTER!! 84 // DISASTER!!
85 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); 85 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID);
86 PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); 86 PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase);
87 // Something is very messed up and a crash is in our future. 87 // Something is very messed up and a crash is in our future.
88 return; 88 return;
89 } 89 }
90 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}", 90 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}",
91 ID, verticesCount, indicesCount); 91 ID, verticesCount, indicesCount);
92 92
93 m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, 93 m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
94 indicesCount, indices, verticesCount, vertices), 94 indicesCount, indices, verticesCount, vertices),
95 PhysicsShapeType.SHAPE_MESH); 95 PhysicsShapeType.SHAPE_MESH);
96 if (m_terrainShape.ptr == IntPtr.Zero) 96 if (m_terrainShape.ptr == IntPtr.Zero)
97 { 97 {
98 // DISASTER!! 98 // DISASTER!!
99 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); 99 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID);
100 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); 100 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase);
101 // Something is very messed up and a crash is in our future. 101 // Something is very messed up and a crash is in our future.
102 return; 102 return;
103 } 103 }
104 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape); 104 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape);
105 105
106 // The terrain object initial position is at the center of the object 106 // The terrain object initial position is at the center of the object
107 Vector3 centerPos; 107 Vector3 centerPos;
108 centerPos.X = minCoords.X + (m_sizeX / 2f); 108 centerPos.X = minCoords.X + (m_sizeX / 2f);
109 centerPos.Y = minCoords.Y + (m_sizeY / 2f); 109 centerPos.Y = minCoords.Y + (m_sizeY / 2f);
110 centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f); 110 centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f);
111 Quaternion rot = Quaternion.Identity; 111 Quaternion rot = Quaternion.Identity;
112 112
113 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot); 113 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot);
114 m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( 114 m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2(
115 m_terrainShape.ptr, ID, centerPos, rot)); 115 m_terrainShape.ptr, ID, centerPos, rot));
116 if (m_terrainBody.ptr == IntPtr.Zero) 116 if (m_terrainBody.ptr == IntPtr.Zero)
117 { 117 {
118 // DISASTER!! 118 // DISASTER!!
119 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); 119 physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
120 // Something is very messed up and a crash is in our future. 120 // Something is very messed up and a crash is in our future.
121 return; 121 return;
122 } 122 }
123 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody); 123 PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody);
124 124
125 // Set current terrain attributes 125 // Set current terrain attributes
126 BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); 126 BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction);
127 BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); 127 BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction);
128 BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution); 128 BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution);
129 BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 129 BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
130 130
131 // Static objects are not very massive. 131 // Static objects are not very massive.
132 BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); 132 BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero);
133 133
134 // Return the new terrain to the world of physical objects 134 // Return the new terrain to the world of physical objects
135 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); 135 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
136 136
137 // redo its bounding box now that it is in the world 137 // redo its bounding box now that it is in the world
138 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); 138 BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr);
139 139
140 BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, 140 BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr,
141 (uint)CollisionFilterGroups.TerrainFilter, 141 (uint)CollisionFilterGroups.TerrainFilter,
142 (uint)CollisionFilterGroups.TerrainMask); 142 (uint)CollisionFilterGroups.TerrainMask);
143 143
144 // Make it so the terrain will not move or be considered for movement. 144 // Make it so the terrain will not move or be considered for movement.
145 BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); 145 BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
146 } 146 }
147 147
148 public override void Dispose() 148 public override void Dispose()
149 { 149 {
150 if (m_terrainBody.ptr != IntPtr.Zero) 150 if (m_terrainBody.ptr != IntPtr.Zero)
151 { 151 {
152 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); 152 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
153 // Frees both the body and the shape. 153 // Frees both the body and the shape.
154 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); 154 BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr);
155 } 155 }
156 } 156 }
157 157
158 public override float GetHeightAtXYZ(Vector3 pos) 158 public override float GetHeightAtXYZ(Vector3 pos)
159 { 159 {
160 // For the moment use the saved heightmap to get the terrain height. 160 // For the moment use the saved heightmap to get the terrain height.
161 // TODO: raycast downward to find the true terrain below the position. 161 // TODO: raycast downward to find the true terrain below the position.
162 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 162 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
163 163
164 int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X; 164 int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X;
165 try 165 try
166 { 166 {
167 ret = m_savedHeightMap[mapIndex]; 167 ret = m_savedHeightMap[mapIndex];
168 } 168 }
169 catch 169 catch
170 { 170 {
171 // Sometimes they give us wonky values of X and Y. Give a warning and return something. 171 // Sometimes they give us wonky values of X and Y. Give a warning and return something.
172 PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", 172 PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
173 LogHeader, TerrainBase, pos); 173 LogHeader, TerrainBase, pos);
174 ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 174 ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
175 } 175 }
176 return ret; 176 return ret;
177 } 177 }
178 178
179 // Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). 179 // Convert the passed heightmap to mesh information suitable for CreateMeshShape2().
180 // Return 'true' if successfully created. 180 // Return 'true' if successfully created.
181 public static bool ConvertHeightmapToMesh( 181 public static bool ConvertHeightmapToMesh(
182 BSScene physicsScene, 182 BSScene physicsScene,
183 float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap 183 float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap
184 float extentX, float extentY, // zero based range for output vertices 184 float extentX, float extentY, // zero based range for output vertices
185 Vector3 extentBase, // base to be added to all vertices 185 Vector3 extentBase, // base to be added to all vertices
186 float magnification, // number of vertices to create between heightMap coords 186 float magnification, // number of vertices to create between heightMap coords
187 out int indicesCountO, out int[] indicesO, 187 out int indicesCountO, out int[] indicesO,
188 out int verticesCountO, out float[] verticesO) 188 out int verticesCountO, out float[] verticesO)
189 { 189 {
190 bool ret = false; 190 bool ret = false;
191 191
192 int indicesCount = 0; 192 int indicesCount = 0;
193 int verticesCount = 0; 193 int verticesCount = 0;
194 int[] indices = new int[0]; 194 int[] indices = new int[0];
195 float[] vertices = new float[0]; 195 float[] vertices = new float[0];
196 196
197 // Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY. 197 // Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY.
198 // TODO: do a more general solution that scales, adds new vertices and smoothes the result. 198 // TODO: do a more general solution that scales, adds new vertices and smoothes the result.
199 199
200 try 200 try
201 { 201 {
202 // One vertice per heightmap value plus the vertices off the top and bottom edge. 202 // One vertice per heightmap value plus the vertices off the top and bottom edge.
203 int totalVertices = (sizeX + 1) * (sizeY + 1); 203 int totalVertices = (sizeX + 1) * (sizeY + 1);
204 vertices = new float[totalVertices * 3]; 204 vertices = new float[totalVertices * 3];
205 int totalIndices = sizeX * sizeY * 6; 205 int totalIndices = sizeX * sizeY * 6;
206 indices = new int[totalIndices]; 206 indices = new int[totalIndices];
207 207
208 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}", 208 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}",
209 BSScene.DetailLogZero, totalVertices, totalIndices); 209 BSScene.DetailLogZero, totalVertices, totalIndices);
210 float magX = (float)sizeX / extentX; 210 float magX = (float)sizeX / extentX;
211 float magY = (float)sizeY / extentY; 211 float magY = (float)sizeY / extentY;
212 // Note that sizeX+1 vertices are created since there is land between this and the next region. 212 // Note that sizeX+1 vertices are created since there is land between this and the next region.
213 for (int yy = 0; yy <= sizeY; yy++) 213 for (int yy = 0; yy <= sizeY; yy++)
214 { 214 {
215 for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times 215 for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times
216 { 216 {
217 int offset = yy * sizeX + xx; 217 int offset = yy * sizeX + xx;
218 // Extend the height from the height from the last row or column 218 // Extend the height from the height from the last row or column
219 if (yy == sizeY) offset -= sizeX; 219 if (yy == sizeY) offset -= sizeX;
220 if (xx == sizeX) offset -= 1; 220 if (xx == sizeX) offset -= 1;
221 float height = heightMap[offset]; 221 float height = heightMap[offset];
222 vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; 222 vertices[verticesCount + 0] = (float)xx * magX + extentBase.X;
223 vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; 223 vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y;
224 vertices[verticesCount + 2] = height + extentBase.Z; 224 vertices[verticesCount + 2] = height + extentBase.Z;
225 if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG 225 if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG
226 { 226 {
227 Vector3 genVertex = new Vector3( 227 Vector3 genVertex = new Vector3(
228 vertices[verticesCount + 0], 228 vertices[verticesCount + 0],
229 vertices[verticesCount + 1], 229 vertices[verticesCount + 1],
230 vertices[verticesCount + 2]); 230 vertices[verticesCount + 2]);
231 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}", 231 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}",
232 BSScene.DetailLogZero, verticesCount/3, genVertex); 232 BSScene.DetailLogZero, verticesCount/3, genVertex);
233 } 233 }
234 verticesCount += 3; 234 verticesCount += 3;
235 } 235 }
236 } 236 }
237 verticesCount = verticesCount / 3; 237 verticesCount = verticesCount / 3;
238 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", 238 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}",
239 BSScene.DetailLogZero, verticesCount); 239 BSScene.DetailLogZero, verticesCount);
240 240
241 for (int yy = 0; yy < sizeY; yy++) 241 for (int yy = 0; yy < sizeY; yy++)
242 { 242 {
243 for (int xx = 0; xx < sizeX; xx++) 243 for (int xx = 0; xx < sizeX; xx++)
244 { 244 {
245 int offset = yy * sizeX + xx; 245 int offset = yy * sizeX + xx;
246 // Each vertices is presumed to be the upper left corner of a box of two triangles 246 // Each vertices is presumed to be the upper left corner of a box of two triangles
247 indices[indicesCount + 0] = offset; 247 indices[indicesCount + 0] = offset;
248 indices[indicesCount + 1] = offset + 1; 248 indices[indicesCount + 1] = offset + 1;
249 indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column 249 indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column
250 indices[indicesCount + 3] = offset + 1; 250 indices[indicesCount + 3] = offset + 1;
251 indices[indicesCount + 4] = offset + sizeX + 2; 251 indices[indicesCount + 4] = offset + sizeX + 2;
252 indices[indicesCount + 5] = offset + sizeX + 1; 252 indices[indicesCount + 5] = offset + sizeX + 1;
253 if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG 253 if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG
254 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG 254 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG
255 BSScene.DetailLogZero, 255 BSScene.DetailLogZero,
256 indices[indicesCount + 0], 256 indices[indicesCount + 0],
257 indices[indicesCount + 1], 257 indices[indicesCount + 1],
258 indices[indicesCount + 2], 258 indices[indicesCount + 2],
259 indices[indicesCount + 3], 259 indices[indicesCount + 3],
260 indices[indicesCount + 4], 260 indices[indicesCount + 4],
261 indices[indicesCount + 5] 261 indices[indicesCount + 5]
262 ); 262 );
263 indicesCount += 6; 263 indicesCount += 6;
264 } 264 }
265 } 265 }
266 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG 266 physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG
267 LogHeader, indicesCount); // DEBUG 267 LogHeader, indicesCount); // DEBUG
268 ret = true; 268 ret = true;
269 } 269 }
270 catch (Exception e) 270 catch (Exception e)
271 { 271 {
272 physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}", 272 physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}",
273 LogHeader, extentBase, e); 273 LogHeader, extentBase, e);
274 } 274 }
275 275
276 indicesCountO = indicesCount; 276 indicesCountO = indicesCount;
277 indicesO = indices; 277 indicesO = indices;
278 verticesCountO = verticesCount; 278 verticesCountO = verticesCount;
279 verticesO = vertices; 279 verticesO = vertices;
280 280
281 return ret; 281 return ret;
282 } 282 }
283} 283}
284} 284}