clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 using System;
28 using System.Collections.Generic;
29 using System.Text;
30  
31 using OpenSim.Framework;
32 using OpenSim.Region.Framework;
33 using OpenSim.Region.CoreModules;
34 using OpenSim.Region.Physics.Manager;
35  
36 using Nini.Config;
37 using log4net;
38  
39 using OpenMetaverse;
40  
41 namespace OpenSim.Region.Physics.BulletSPlugin
42 {
43 public sealed class BSTerrainHeightmap : BSTerrainPhys
44 {
45 static string LogHeader = "[BULLETSIM TERRAIN HEIGHTMAP]";
46  
47 BulletHMapInfo m_mapInfo = null;
48  
49 // Constructor to build a default, flat heightmap terrain.
50 public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, Vector3 regionSize)
51 : base(physicsScene, regionBase, id)
52 {
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);
55 int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
56 float[] initialMap = new float[totalHeights];
57 for (int ii = 0; ii < totalHeights; ii++)
58 {
59 initialMap[ii] = BSTerrainManager.HEIGHT_INITIALIZATION;
60 }
61 m_mapInfo = new BulletHMapInfo(id, initialMap, regionSize.X, regionSize.Y);
62 m_mapInfo.minCoords = minTerrainCoords;
63 m_mapInfo.maxCoords = maxTerrainCoords;
64 m_mapInfo.terrainRegionBase = TerrainBase;
65 // Don't have to free any previous since we just got here.
66 BuildHeightmapTerrain();
67 }
68  
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).
71 public BSTerrainHeightmap(BSScene physicsScene, Vector3 regionBase, uint id, float[] initialMap,
72 Vector3 minCoords, Vector3 maxCoords)
73 : base(physicsScene, regionBase, id)
74 {
75 m_mapInfo = new BulletHMapInfo(id, initialMap, maxCoords.X - minCoords.X, maxCoords.Y - minCoords.Y);
76 m_mapInfo.minCoords = minCoords;
77 m_mapInfo.maxCoords = maxCoords;
78 m_mapInfo.minZ = minCoords.Z;
79 m_mapInfo.maxZ = maxCoords.Z;
80 m_mapInfo.terrainRegionBase = TerrainBase;
81  
82 // Don't have to free any previous since we just got here.
83 BuildHeightmapTerrain();
84 }
85  
86 public override void Dispose()
87 {
88 ReleaseHeightMapTerrain();
89 }
90  
91 // Using the information in m_mapInfo, create the physical representation of the heightmap.
92 private void BuildHeightmapTerrain()
93 {
94 // Create the terrain shape from the mapInfo
95 m_mapInfo.terrainShape = m_physicsScene.PE.CreateTerrainShape( m_mapInfo.ID,
96 new Vector3(m_mapInfo.sizeX, m_mapInfo.sizeY, 0), m_mapInfo.minZ, m_mapInfo.maxZ,
97 m_mapInfo.heightMap, 1f, BSParam.TerrainCollisionMargin);
98  
99  
100 // The terrain object initial position is at the center of the object
101 Vector3 centerPos;
102 centerPos.X = m_mapInfo.minCoords.X + (m_mapInfo.sizeX / 2f);
103 centerPos.Y = m_mapInfo.minCoords.Y + (m_mapInfo.sizeY / 2f);
104 centerPos.Z = m_mapInfo.minZ + ((m_mapInfo.maxZ - m_mapInfo.minZ) / 2f);
105  
106 m_mapInfo.terrainBody = m_physicsScene.PE.CreateBodyWithDefaultMotionState(m_mapInfo.terrainShape,
107 m_mapInfo.ID, centerPos, Quaternion.Identity);
108  
109 // Set current terrain attributes
110 m_physicsScene.PE.SetFriction(m_mapInfo.terrainBody, BSParam.TerrainFriction);
111 m_physicsScene.PE.SetHitFraction(m_mapInfo.terrainBody, BSParam.TerrainHitFraction);
112 m_physicsScene.PE.SetRestitution(m_mapInfo.terrainBody, BSParam.TerrainRestitution);
113 m_physicsScene.PE.SetCollisionFlags(m_mapInfo.terrainBody, CollisionFlags.CF_STATIC_OBJECT);
114  
115 m_mapInfo.terrainBody.collisionType = CollisionType.Terrain;
116  
117 // Return the new terrain to the world of physical objects
118 m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, m_mapInfo.terrainBody);
119  
120 // redo its bounding box now that it is in the world
121 m_physicsScene.PE.UpdateSingleAabb(m_physicsScene.World, m_mapInfo.terrainBody);
122  
123 // Make it so the terrain will not move or be considered for movement.
124 m_physicsScene.PE.ForceActivationState(m_mapInfo.terrainBody, ActivationState.DISABLE_SIMULATION);
125  
126 return;
127 }
128  
129 // If there is information in m_mapInfo pointing to physical structures, release same.
130 private void ReleaseHeightMapTerrain()
131 {
132 if (m_mapInfo != null)
133 {
134 if (m_mapInfo.terrainBody.HasPhysicalBody)
135 {
136 m_physicsScene.PE.RemoveObjectFromWorld(m_physicsScene.World, m_mapInfo.terrainBody);
137 // Frees both the body and the shape.
138 m_physicsScene.PE.DestroyObject(m_physicsScene.World, m_mapInfo.terrainBody);
139 }
140 }
141 m_mapInfo = null;
142 }
143  
144 // The passed position is relative to the base of the region.
145 public override float GetTerrainHeightAtXYZ(Vector3 pos)
146 {
147 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
148  
149 int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X;
150 try
151 {
152 ret = m_mapInfo.heightMap[mapIndex];
153 }
154 catch
155 {
156 // Sometimes they give us wonky values of X and Y. Give a warning and return something.
157 m_physicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, pos={2}",
158 LogHeader, m_mapInfo.terrainRegionBase, pos);
159 ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
160 }
161 return ret;
162 }
163  
164 // The passed position is relative to the base of the region.
165 public override float GetWaterLevelAtXYZ(Vector3 pos)
166 {
167 return m_physicsScene.SimpleWaterLevel;
168 }
169 }
170 }