BulletSim: fix line endings to be all Linux style (windows style keeps creeping in)

connector_plugin
Robert Adams 2012-11-20 20:38:51 -08:00
parent 34cbc738a8
commit 2dc7e9d3fa
2 changed files with 454 additions and 454 deletions

View File

@ -1,170 +1,170 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyrightD * * Redistributions in binary form must reproduce the above copyrightD
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the * * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework; using OpenSim.Region.Framework;
using OpenSim.Region.CoreModules; using OpenSim.Region.CoreModules;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using Nini.Config; using Nini.Config;
using log4net; using log4net;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin namespace OpenSim.Region.Physics.BulletSPlugin
{ {
public sealed class BSTerrainHeightmap : BSTerrainPhys public sealed class BSTerrainHeightmap : BSTerrainPhys
{ {
static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]"; static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]";
BulletHeightMapInfo m_mapInfo = null; BulletHeightMapInfo m_mapInfo = null;
// Constructor to build a default, flat heightmap terrain. // Constructor to build a default, flat heightmap terrain.
public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
: base(physicsScene, regionBase, id) : base(physicsScene, regionBase, id)
{ {
Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE); Vector3 minTerrainCoords = new Vector3(0f, 0f, BSTerrainManager.HEIGHT_INITIALIZATION - BSTerrainManager.HEIGHT_EQUAL_FUDGE);
Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION); Vector3 maxTerrainCoords = new Vector3(regionSize.X, regionSize.Y, BSTerrainManager.HEIGHT_INITIALIZATION);
int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
float[] initialMap = new float[totalHeights]; float[] initialMap = new float[totalHeights];
for (int ii = 0; ii < totalHeights; ii++) for (int ii = 0; ii < totalHeights; ii++)
{ {
initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION; initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION;
} }
m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero);
m_mapInfo.minCoords = minTerrainCoords; m_mapInfo.minCoords = minTerrainCoords;
m_mapInfo.maxCoords = maxTerrainCoords; m_mapInfo.maxCoords = maxTerrainCoords;
m_mapInfo.terrainRegionBase = TerrainBase; m_mapInfo.terrainRegionBase = TerrainBase;
// Don't have to free any previous since we just got here. // Don't have to free any previous since we just got here.
BuildHeightmapTerrain(); BuildHeightmapTerrain();
} }
// This minCoords and maxCoords passed in give the size of the terrain (min and max Z // This minCoords and maxCoords passed in give the size of the terrain (min and max Z
// are the high and low points of the heightmap). // are the high and low points of the heightmap).
public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
Vector3 minCoords, Vector3 maxCoords) Vector3 minCoords, Vector3 maxCoords)
: base(physicsScene, regionBase, id) : base(physicsScene, regionBase, id)
{ {
m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero); m_mapInfo = new BulletHeightMapInfo(id, initialMap, IntPtr.Zero);
m_mapInfo.minCoords = minCoords; m_mapInfo.minCoords = minCoords;
m_mapInfo.maxCoords = maxCoords; m_mapInfo.maxCoords = maxCoords;
m_mapInfo.minZ = minCoords.Z; m_mapInfo.minZ = minCoords.Z;
m_mapInfo.maxZ = maxCoords.Z; m_mapInfo.maxZ = maxCoords.Z;
m_mapInfo.terrainRegionBase = TerrainBase; m_mapInfo.terrainRegionBase = TerrainBase;
// Don't have to free any previous since we just got here. // Don't have to free any previous since we just got here.
BuildHeightmapTerrain(); BuildHeightmapTerrain();
} }
public override void Dispose() public override void Dispose()
{ {
ReleaseHeightMapTerrain(); ReleaseHeightMapTerrain();
} }
// Using the information in m_mapInfo, create the physical representation of the heightmap. // Using the information in m_mapInfo, create the physical representation of the heightmap.
private void BuildHeightmapTerrain() private void BuildHeightmapTerrain()
{ {
m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID,
m_mapInfo.minCoords, m_mapInfo.maxCoords, m_mapInfo.minCoords, m_mapInfo.maxCoords,
m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN);
// Create the terrain shape from the mapInfo // Create the terrain shape from the mapInfo
m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr),
PhysicsShapeType.SHAPE_TERRAIN); PhysicsShapeType.SHAPE_TERRAIN);
// The terrain object initial position is at the center of the object // The terrain object initial position is at the center of the object
Vector3 centerPos; Vector3 centerPos;
centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f); centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f);
centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f); centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f); centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f);
m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID, m_mapInfo.terrainBody = new BulletBody(m_mapInfo.ID,
BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr, BulletSimAPI.CreateBodyWithDefaultMotionState2(m_mapInfo.terrainShape.ptr,
m_mapInfo.ID, centerPos, Quaternion.Identity)); m_mapInfo.ID, centerPos, Quaternion.Identity));
// Set current terrain attributes // Set current terrain attributes
BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); BulletSimAPI.SetFriction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction);
BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); BulletSimAPI.SetHitFraction2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction);
BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); BulletSimAPI.SetRestitution2(m_mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution);
BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); BulletSimAPI.SetCollisionFlags2(m_mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
// Return the new terrain to the world of physical objects // Return the new terrain to the world of physical objects
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
// redo its bounding box now that it is in the world // redo its bounding box now that it is in the world
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr, BulletSimAPI.SetCollisionFilterMask2(m_mapInfo.terrainBody.ptr,
(uint)CollisionFilterGroups.TerrainFilter, (uint)CollisionFilterGroups.TerrainFilter,
(uint)CollisionFilterGroups.TerrainMask); (uint)CollisionFilterGroups.TerrainMask);
// Make it so the terrain will not move or be considered for movement. // Make it so the terrain will not move or be considered for movement.
BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
return; return;
} }
// If there is information in m_mapInfo pointing to physical structures, release same. // If there is information in m_mapInfo pointing to physical structures, release same.
private void ReleaseHeightMapTerrain() private void ReleaseHeightMapTerrain()
{ {
if (m_mapInfo != null) if (m_mapInfo != null)
{ {
if (m_mapInfo.terrainBody.ptr != IntPtr.Zero) if (m_mapInfo.terrainBody.ptr != IntPtr.Zero)
{ {
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
// Frees both the body and the shape. // Frees both the body and the shape.
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr); BulletSimAPI.ReleaseHeightMapInfo2(m_mapInfo.Ptr);
} }
} }
m_mapInfo = null; m_mapInfo = null;
} }
// The passed position is relative to the base of the region. // The passed position is relative to the base of the region.
public override float GetHeightAtXYZ(Vector3 pos) public override float GetHeightAtXYZ(Vector3 pos)
{ {
float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X;
try try
{ {
ret = m_mapInfo.heightMap[mapIndex]; ret = m_mapInfo.heightMap[mapIndex];
} }
catch catch
{ {
// Sometimes they give us wonky values of X and Y. Give a warning and return something. // Sometimes they give us wonky values of X and Y. Give a warning and return something.
PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
LogHeader, m_mapInfo.terrainRegionBase, pos); LogHeader, m_mapInfo.terrainRegionBase, pos);
ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
} }
return ret; return ret;
} }
} }
} }

View File

@ -1,284 +1,284 @@
/* /*
* Copyright (c) Contributors, http://opensimulator.org/ * Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders. * See CONTRIBUTORS.TXT for a full list of copyright holders.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright * * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyrightD * * Redistributions in binary form must reproduce the above copyrightD
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the * * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products * names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission. * derived from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework; using OpenSim.Region.Framework;
using OpenSim.Region.CoreModules; using OpenSim.Region.CoreModules;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using Nini.Config; using Nini.Config;
using log4net; using log4net;
using OpenMetaverse; using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin namespace OpenSim.Region.Physics.BulletSPlugin
{ {
public sealed class BSTerrainMesh : BSTerrainPhys public sealed class BSTerrainMesh : BSTerrainPhys
{ {
static string LogHeader = "[BULLETSIM TERRAIN MESH]"; static string LogHeader = "[BULLETSIM TERRAIN MESH]";
private float[] m_savedHeightMap; private float[] m_savedHeightMap;
int m_sizeX; int m_sizeX;
int m_sizeY; int m_sizeY;
BulletShape m_terrainShape; BulletShape m_terrainShape;
BulletBody m_terrainBody; BulletBody m_terrainBody;
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize) public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
: base(physicsScene, regionBase, id) : base(physicsScene, regionBase, id)
{ {
} }
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */) public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id /* parameters for making mesh */)
: base(physicsScene, regionBase, id) : base(physicsScene, regionBase, id)
{ {
} }
// Create terrain mesh from a heightmap. // Create terrain mesh from a heightmap.
public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap, public BSTerrainMesh(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
Vector3 minCoords, Vector3 maxCoords) Vector3 minCoords, Vector3 maxCoords)
: base(physicsScene, regionBase, id) : base(physicsScene, regionBase, id)
{ {
int indicesCount; int indicesCount;
int[] indices; int[] indices;
int verticesCount; int verticesCount;
float[] vertices; float[] vertices;
m_savedHeightMap = initialMap; m_savedHeightMap = initialMap;
m_sizeX = (int)(maxCoords.X - minCoords.X); m_sizeX = (int)(maxCoords.X - minCoords.X);
m_sizeY = (int)(maxCoords.Y - minCoords.Y); m_sizeY = (int)(maxCoords.Y - minCoords.Y);
if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY, if (!BSTerrainMesh.ConvertHeightmapToMesh(PhysicsScene, initialMap, m_sizeX, m_sizeY,
(float)m_sizeX, (float)m_sizeY, (float)m_sizeX, (float)m_sizeY,
Vector3.Zero, 1.0f, Vector3.Zero, 1.0f,
out indicesCount, out indices, out verticesCount, out vertices)) out indicesCount, out indices, out verticesCount, out vertices))
{ {
// DISASTER!! // DISASTER!!
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID); PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedConversionOfHeightmap", ID);
PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase); PhysicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh! base={1}", LogHeader, TerrainBase);
// Something is very messed up and a crash is in our future. // Something is very messed up and a crash is in our future.
return; return;
} }
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}", PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterConvertHeightmapToMesh,ver={1},ind={2}",
ID, verticesCount, indicesCount); ID, verticesCount, indicesCount);
m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr,
indicesCount, indices, verticesCount, vertices), indicesCount, indices, verticesCount, vertices),
PhysicsShapeType.SHAPE_MESH); PhysicsShapeType.SHAPE_MESH);
if (m_terrainShape.ptr == IntPtr.Zero) if (m_terrainShape.ptr == IntPtr.Zero)
{ {
// DISASTER!! // DISASTER!!
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID); PhysicsScene.DetailLog("{0},BSTerrainMesh.create,failedCreationOfShape", ID);
physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase); physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain mesh! base={1}", LogHeader, TerrainBase);
// Something is very messed up and a crash is in our future. // Something is very messed up and a crash is in our future.
return; return;
} }
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape); PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateShape,shape={1}", ID, m_terrainShape);
// The terrain object initial position is at the center of the object // The terrain object initial position is at the center of the object
Vector3 centerPos; Vector3 centerPos;
centerPos.X = minCoords.X + (m_sizeX / 2f); centerPos.X = minCoords.X + (m_sizeX / 2f);
centerPos.Y = minCoords.Y + (m_sizeY / 2f); centerPos.Y = minCoords.Y + (m_sizeY / 2f);
centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f); centerPos.Z = minCoords.Z + ((maxCoords.Z - minCoords.Z) / 2f);
Quaternion rot = Quaternion.Identity; Quaternion rot = Quaternion.Identity;
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot); PhysicsScene.DetailLog("{0},BSTerrainMesh.create,creatingBody,centerPos={1},rot={2}", ID, centerPos, rot);
m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2( m_terrainBody = new BulletBody(id, BulletSimAPI.CreateBodyWithDefaultMotionState2(
m_terrainShape.ptr, ID, centerPos, rot)); m_terrainShape.ptr, ID, centerPos, rot));
if (m_terrainBody.ptr == IntPtr.Zero) if (m_terrainBody.ptr == IntPtr.Zero)
{ {
// DISASTER!! // DISASTER!!
physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase); physicsScene.Logger.ErrorFormat("{0} Failed creation of terrain body! base={1}", LogHeader, TerrainBase);
// Something is very messed up and a crash is in our future. // Something is very messed up and a crash is in our future.
return; return;
} }
PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody); PhysicsScene.DetailLog("{0},BSTerrainMesh.create,afterCreateBody,body={1}", ID, m_terrainBody);
// Set current terrain attributes // Set current terrain attributes
BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction); BulletSimAPI.SetFriction2(m_terrainBody.ptr, PhysicsScene.Params.terrainFriction);
BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); BulletSimAPI.SetHitFraction2(m_terrainBody.ptr, PhysicsScene.Params.terrainHitFraction);
BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution); BulletSimAPI.SetRestitution2(m_terrainBody.ptr, PhysicsScene.Params.terrainRestitution);
BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); BulletSimAPI.SetCollisionFlags2(m_terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
// Static objects are not very massive. // Static objects are not very massive.
BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero);
// Return the new terrain to the world of physical objects // Return the new terrain to the world of physical objects
BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
// redo its bounding box now that it is in the world // redo its bounding box now that it is in the world
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr);
BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr,
(uint)CollisionFilterGroups.TerrainFilter, (uint)CollisionFilterGroups.TerrainFilter,
(uint)CollisionFilterGroups.TerrainMask); (uint)CollisionFilterGroups.TerrainMask);
// Make it so the terrain will not move or be considered for movement. // Make it so the terrain will not move or be considered for movement.
BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
} }
public override void Dispose() public override void Dispose()
{ {
if (m_terrainBody.ptr != IntPtr.Zero) if (m_terrainBody.ptr != IntPtr.Zero)
{ {
BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr);
// Frees both the body and the shape. // Frees both the body and the shape.
BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_terrainBody.ptr);
} }
} }
public override float GetHeightAtXYZ(Vector3 pos) public override float GetHeightAtXYZ(Vector3 pos)
{ {
// For the moment use the saved heightmap to get the terrain height. // For the moment use the saved heightmap to get the terrain height.
// TODO: raycast downward to find the true terrain below the position. // TODO: raycast downward to find the true terrain below the position.
float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X; int mapIndex = (int)pos.Y * m_sizeY + (int)pos.X;
try try
{ {
ret = m_savedHeightMap[mapIndex]; ret = m_savedHeightMap[mapIndex];
} }
catch catch
{ {
// Sometimes they give us wonky values of X and Y. Give a warning and return something. // Sometimes they give us wonky values of X and Y. Give a warning and return something.
PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}", PhysicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
LogHeader, TerrainBase, pos); LogHeader, TerrainBase, pos);
ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
} }
return ret; return ret;
} }
// Convert the passed heightmap to mesh information suitable for CreateMeshShape2(). // Convert the passed heightmap to mesh information suitable for CreateMeshShape2().
// Return 'true' if successfully created. // Return 'true' if successfully created.
public static bool ConvertHeightmapToMesh( public static bool ConvertHeightmapToMesh(
BSScene physicsScene, BSScene physicsScene,
float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap float[] heightMap, int sizeX, int sizeY, // parameters of incoming heightmap
float extentX, float extentY, // zero based range for output vertices float extentX, float extentY, // zero based range for output vertices
Vector3 extentBase, // base to be added to all vertices Vector3 extentBase, // base to be added to all vertices
float magnification, // number of vertices to create between heightMap coords float magnification, // number of vertices to create between heightMap coords
out int indicesCountO, out int[] indicesO, out int indicesCountO, out int[] indicesO,
out int verticesCountO, out float[] verticesO) out int verticesCountO, out float[] verticesO)
{ {
bool ret = false; bool ret = false;
int indicesCount = 0; int indicesCount = 0;
int verticesCount = 0; int verticesCount = 0;
int[] indices = new int[0]; int[] indices = new int[0];
float[] vertices = new float[0]; float[] vertices = new float[0];
// Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY. // Simple mesh creation which assumes magnification == 1, sizeX == extentX and sizeY == extentY.
// TODO: do a more general solution that scales, adds new vertices and smoothes the result. // TODO: do a more general solution that scales, adds new vertices and smoothes the result.
try try
{ {
// One vertice per heightmap value plus the vertices off the top and bottom edge. // One vertice per heightmap value plus the vertices off the top and bottom edge.
int totalVertices = (sizeX + 1) * (sizeY + 1); int totalVertices = (sizeX + 1) * (sizeY + 1);
vertices = new float[totalVertices * 3]; vertices = new float[totalVertices * 3];
int totalIndices = sizeX * sizeY * 6; int totalIndices = sizeX * sizeY * 6;
indices = new int[totalIndices]; indices = new int[totalIndices];
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}", physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2}",
BSScene.DetailLogZero, totalVertices, totalIndices); BSScene.DetailLogZero, totalVertices, totalIndices);
float magX = (float)sizeX / extentX; float magX = (float)sizeX / extentX;
float magY = (float)sizeY / extentY; float magY = (float)sizeY / extentY;
// Note that sizeX+1 vertices are created since there is land between this and the next region. // Note that sizeX+1 vertices are created since there is land between this and the next region.
for (int yy = 0; yy <= sizeY; yy++) for (int yy = 0; yy <= sizeY; yy++)
{ {
for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times
{ {
int offset = yy * sizeX + xx; int offset = yy * sizeX + xx;
// Extend the height from the height from the last row or column // Extend the height from the height from the last row or column
if (yy == sizeY) offset -= sizeX; if (yy == sizeY) offset -= sizeX;
if (xx == sizeX) offset -= 1; if (xx == sizeX) offset -= 1;
float height = heightMap[offset]; float height = heightMap[offset];
vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; vertices[verticesCount + 0] = (float)xx * magX + extentBase.X;
vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y;
vertices[verticesCount + 2] = height + extentBase.Z; vertices[verticesCount + 2] = height + extentBase.Z;
if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG if (physicsScene.PhysicsLogging.Enabled && verticesCount < 900) // DEBUG DEBUG DEBUG
{ {
Vector3 genVertex = new Vector3( Vector3 genVertex = new Vector3(
vertices[verticesCount + 0], vertices[verticesCount + 0],
vertices[verticesCount + 1], vertices[verticesCount + 1],
vertices[verticesCount + 2]); vertices[verticesCount + 2]);
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}", physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,ii={1},vertex={2}",
BSScene.DetailLogZero, verticesCount/3, genVertex); BSScene.DetailLogZero, verticesCount/3, genVertex);
} }
verticesCount += 3; verticesCount += 3;
} }
} }
verticesCount = verticesCount / 3; verticesCount = verticesCount / 3;
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}",
BSScene.DetailLogZero, verticesCount); BSScene.DetailLogZero, verticesCount);
for (int yy = 0; yy < sizeY; yy++) for (int yy = 0; yy < sizeY; yy++)
{ {
for (int xx = 0; xx < sizeX; xx++) for (int xx = 0; xx < sizeX; xx++)
{ {
int offset = yy * sizeX + xx; int offset = yy * sizeX + xx;
// Each vertices is presumed to be the upper left corner of a box of two triangles // Each vertices is presumed to be the upper left corner of a box of two triangles
indices[indicesCount + 0] = offset; indices[indicesCount + 0] = offset;
indices[indicesCount + 1] = offset + 1; indices[indicesCount + 1] = offset + 1;
indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column indices[indicesCount + 2] = offset + sizeX + 1; // accounting for the extra column
indices[indicesCount + 3] = offset + 1; indices[indicesCount + 3] = offset + 1;
indices[indicesCount + 4] = offset + sizeX + 2; indices[indicesCount + 4] = offset + sizeX + 2;
indices[indicesCount + 5] = offset + sizeX + 1; indices[indicesCount + 5] = offset + sizeX + 1;
if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG if (indicesCount < (300 * 6)) // DEBUG DEBUG DEBUG
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,i0={1},i1={2},i2={3},i3={4},i4={5},i5={6}", // DEEBUG DEBUG DEBUG
BSScene.DetailLogZero, BSScene.DetailLogZero,
indices[indicesCount + 0], indices[indicesCount + 0],
indices[indicesCount + 1], indices[indicesCount + 1],
indices[indicesCount + 2], indices[indicesCount + 2],
indices[indicesCount + 3], indices[indicesCount + 3],
indices[indicesCount + 4], indices[indicesCount + 4],
indices[indicesCount + 5] indices[indicesCount + 5]
); );
indicesCount += 6; indicesCount += 6;
} }
} }
physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG
LogHeader, indicesCount); // DEBUG LogHeader, indicesCount); // DEBUG
ret = true; ret = true;
} }
catch (Exception e) catch (Exception e)
{ {
physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}", physicsScene.Logger.ErrorFormat("{0} Failed conversion of heightmap to mesh. Base={1}, e={2}",
LogHeader, extentBase, e); LogHeader, extentBase, e);
} }
indicesCountO = indicesCount; indicesCountO = indicesCount;
indicesO = indices; indicesO = indices;
verticesCountO = verticesCount; verticesCountO = verticesCount;
verticesO = vertices; verticesO = vertices;
return ret; return ret;
} }
} }
} }