Annotation of /trunk/ModularRex/RexOdePlugin/RexOdePrim.cs
Parent Directory
|
Revision Log
Revision 53 - (view) (download)
| 1 : | tuco | 50 | using System; |
| 2 : | using System.Collections.Generic; | ||
| 3 : | using System.Reflection; | ||
| 4 : | using System.Runtime.InteropServices; | ||
| 5 : | using System.Threading; | ||
| 6 : | using log4net; | ||
| 7 : | using OpenMetaverse; | ||
| 8 : | using Ode.NET; | ||
| 9 : | using OpenSim.Framework; | ||
| 10 : | using OpenSim.Region.Physics.Manager; | ||
| 11 : | using OpenSim.Region.Physics.OdePlugin; | ||
| 12 : | using OpenSim.Region.Physics.Meshing; | ||
| 13 : | |||
| 14 : | |||
| 15 : | namespace ModularRex.RexOdePlugin | ||
| 16 : | { | ||
| 17 : | public class RexOdePrim : OdePrim | ||
| 18 : | { | ||
| 19 : | protected Mesh m_OriginalMesh = null; | ||
| 20 : | |||
| 21 : | protected bool m_DotMeshCollision = false; | ||
| 22 : | protected bool m_PrimVolume = false; | ||
| 23 : | protected bool m_ReCreateCollision = false; | ||
| 24 : | |||
| 25 : | protected bool m_BoundsScaling = false; | ||
| 26 : | protected PhysicsVector m_BoundsMin = new PhysicsVector(0, 0, 0); | ||
| 27 : | protected PhysicsVector m_BoundsMax = new PhysicsVector(0, 0, 0); | ||
| 28 : | |||
| 29 : | public RexOdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size, | ||
| 30 : | Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) | ||
| 31 : | :base(primName, parent_scene, pos, size,rotation, mesh, pbs, pisPhysical, dode) | ||
| 32 : | { | ||
| 33 : | |||
| 34 : | } | ||
| 35 : | |||
| 36 : | // Override, take collisionmesh into account | ||
| 37 : | public override void ProcessTaints(float timestep) | ||
| 38 : | { | ||
| 39 : | if (m_taintadd) | ||
| 40 : | { | ||
| 41 : | changeadd(timestep); | ||
| 42 : | } | ||
| 43 : | if (prim_geom != IntPtr.Zero) | ||
| 44 : | { | ||
| 45 : | if (!_position.IsIdentical(m_taintposition, 0f)) | ||
| 46 : | changemove(timestep); | ||
| 47 : | |||
| 48 : | if (m_taintrot != _orientation) | ||
| 49 : | { | ||
| 50 : | if(m_DotMeshCollision) // rex | ||
| 51 : | rotateogremesh(timestep); // rex | ||
| 52 : | else | ||
| 53 : | rotate(timestep); | ||
| 54 : | } | ||
| 55 : | // | ||
| 56 : | |||
| 57 : | if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) | ||
| 58 : | changePhysicsStatus(timestep); | ||
| 59 : | // | ||
| 60 : | |||
| 61 : | if (!_size.IsIdentical(m_taintsize, 0)) | ||
| 62 : | { | ||
| 63 : | if(m_DotMeshCollision) | ||
| 64 : | changesizeogremesh(timestep); | ||
| 65 : | else | ||
| 66 : | changesize(timestep); | ||
| 67 : | } | ||
| 68 : | if (m_ReCreateCollision) // rex start | ||
| 69 : | { | ||
| 70 : | if (m_DotMeshCollision) | ||
| 71 : | changesizeogremesh(timestep); | ||
| 72 : | else | ||
| 73 : | changesize(timestep); | ||
| 74 : | } // rex, end | ||
| 75 : | // | ||
| 76 : | |||
| 77 : | if (m_taintshape) | ||
| 78 : | changeshape(timestep); | ||
| 79 : | // | ||
| 80 : | |||
| 81 : | if (m_taintforce) | ||
| 82 : | changeAddForce(timestep); | ||
| 83 : | |||
| 84 : | if (m_taintaddangularforce) | ||
| 85 : | changeAddAngularForce(timestep); | ||
| 86 : | |||
| 87 : | if (!m_taintTorque.IsIdentical(PhysicsVector.Zero, 0.001f)) | ||
| 88 : | changeSetTorque(timestep); | ||
| 89 : | |||
| 90 : | if (m_taintdisable) | ||
| 91 : | changedisable(timestep); | ||
| 92 : | |||
| 93 : | if (m_taintselected != m_isSelected) | ||
| 94 : | changeSelectedStatus(timestep); | ||
| 95 : | |||
| 96 : | if (!m_taintVelocity.IsIdentical(PhysicsVector.Zero, 0.001f)) | ||
| 97 : | changevelocity(timestep); | ||
| 98 : | |||
| 99 : | if (m_taintparent != _parent) | ||
| 100 : | changelink(timestep); | ||
| 101 : | |||
| 102 : | if (m_taintCollidesWater != m_collidesWater) | ||
| 103 : | changefloatonwater(timestep); | ||
| 104 : | |||
| 105 : | if (!m_angularlock.IsIdentical(m_taintAngularLock, 0)) | ||
| 106 : | changeAngularLock(timestep); | ||
| 107 : | } | ||
| 108 : | else | ||
| 109 : | { | ||
| 110 : | m_log.Error("[REXODEPHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)"); | ||
| 111 : | } | ||
| 112 : | } | ||
| 113 : | |||
| 114 : | |||
| 115 : | // This function should be called only outside of simulation loop -> OdeLock used. | ||
| 116 : | tuco | 53 | public override void SetCollisionMesh(byte[] meshdata, string meshname, bool scalemesh) |
| 117 : | tuco | 50 | { |
| 118 : | lock (_parent_scene.OdeLock) | ||
| 119 : | { | ||
| 120 : | m_DotMeshCollision = false; | ||
| 121 : | if (m_OriginalMesh != null) | ||
| 122 : | { | ||
| 123 : | // Never pinned so skip m_OriginalMesh.releasePinned(); | ||
| 124 : | m_OriginalMesh = null; | ||
| 125 : | } | ||
| 126 : | |||
| 127 : | tuco | 53 | if (meshdata != null && CreateOSMeshFromDotMesh(meshdata, meshname, scalemesh)) |
| 128 : | tuco | 50 | m_DotMeshCollision = true; |
| 129 : | |||
| 130 : | m_ReCreateCollision = true; | ||
| 131 : | } | ||
| 132 : | |||
| 133 : | _parent_scene.AddPhysicsActorTaint(this); | ||
| 134 : | } | ||
| 135 : | |||
| 136 : | public override void SetBoundsScaling(bool vbScaleMesh) | ||
| 137 : | { | ||
| 138 : | if (m_DotMeshCollision) | ||
| 139 : | { | ||
| 140 : | m_BoundsScaling = vbScaleMesh; | ||
| 141 : | m_ReCreateCollision = true; | ||
| 142 : | } | ||
| 143 : | } | ||
| 144 : | |||
| 145 : | private bool CreateOSMeshFromDotMesh(byte[] vData, string vMeshName, bool vbScaleMesh) | ||
| 146 : | { | ||
| 147 : | float[] tempVertexList; | ||
| 148 : | float[] tempBounds; | ||
| 149 : | int[] tempIndexList; | ||
| 150 : | string errorMessage; | ||
| 151 : | |||
| 152 : | RexDotMeshLoader.DotMeshLoader.ReadDotMeshModel(vData, out tempVertexList, out tempIndexList, out tempBounds, out errorMessage); | ||
| 153 : | |||
| 154 : | if (tempVertexList == null || tempIndexList == null) | ||
| 155 : | { | ||
| 156 : | m_log.Error("[REXODEPHYSICS]: Error importing mesh:" + vMeshName + ", " + errorMessage); | ||
| 157 : | return false; | ||
| 158 : | } | ||
| 159 : | |||
| 160 : | m_OriginalMesh = new Mesh(); | ||
| 161 : | |||
| 162 : | m_BoundsScaling = vbScaleMesh; | ||
| 163 : | m_BoundsMin.X = tempBounds[0]; | ||
| 164 : | m_BoundsMin.Y = tempBounds[1]; | ||
| 165 : | m_BoundsMin.Z = tempBounds[2]; | ||
| 166 : | m_BoundsMax.X = tempBounds[3]; | ||
| 167 : | m_BoundsMax.Y = tempBounds[4]; | ||
| 168 : | m_BoundsMax.Z = tempBounds[5]; | ||
| 169 : | |||
| 170 : | for (int i = 0; i < tempVertexList.GetLength(0); i=i+3) | ||
| 171 : | { | ||
| 172 : | Vertex vert = new Vertex(tempVertexList[i], tempVertexList[i+1], tempVertexList[i+2]); | ||
| 173 : | m_OriginalMesh.vertices.Add(vert); | ||
| 174 : | } | ||
| 175 : | |||
| 176 : | for (int i = 0; i < tempIndexList.GetLength(0); i=i+3) | ||
| 177 : | { | ||
| 178 : | Triangle tria = new Triangle(m_OriginalMesh.vertices[(tempIndexList[i])], m_OriginalMesh.vertices[(tempIndexList[i+1])], m_OriginalMesh.vertices[(tempIndexList[i+2])]); | ||
| 179 : | m_OriginalMesh.triangles.Add(tria); | ||
| 180 : | } | ||
| 181 : | return true; | ||
| 182 : | } | ||
| 183 : | |||
| 184 : | private Mesh CreateMeshFromOriginal() | ||
| 185 : | { | ||
| 186 : | float[] scalefactor = new float[3]; | ||
| 187 : | |||
| 188 : | if (m_OriginalMesh != null) | ||
| 189 : | { | ||
| 190 : | Mesh newmesh = m_OriginalMesh.Clone(); | ||
| 191 : | |||
| 192 : | PhysicsVector scalingvector = new PhysicsVector(_size.X, _size.Y, _size.Z); | ||
| 193 : | if (m_BoundsScaling) | ||
| 194 : | { | ||
| 195 : | PhysicsVector boundssize = m_BoundsMax - m_BoundsMin; | ||
| 196 : | if (boundssize.X != 0) | ||
| 197 : | scalingvector.X /= boundssize.X; | ||
| 198 : | if (boundssize.Y != 0) | ||
| 199 : | scalingvector.Z /= boundssize.Y; | ||
| 200 : | if (boundssize.Z != 0) | ||
| 201 : | scalingvector.Y /= boundssize.Z; | ||
| 202 : | } | ||
| 203 : | |||
| 204 : | scalefactor[0] = scalingvector.X; | ||
| 205 : | scalefactor[1] = scalingvector.Z; | ||
| 206 : | scalefactor[2] = scalingvector.Y; | ||
| 207 : | |||
| 208 : | for (int i = 0; i < newmesh.vertices.Count;i++) | ||
| 209 : | { | ||
| 210 : | newmesh.vertices[i].X *= scalefactor[0]; | ||
| 211 : | newmesh.vertices[i].Y *= scalefactor[1]; | ||
| 212 : | newmesh.vertices[i].Z *= scalefactor[2]; | ||
| 213 : | } | ||
| 214 : | return newmesh; | ||
| 215 : | } | ||
| 216 : | else | ||
| 217 : | return null; | ||
| 218 : | |||
| 219 : | } | ||
| 220 : | |||
| 221 : | private void rotateogremesh(float timestep) | ||
| 222 : | { | ||
| 223 : | d.Quaternion myrot = new d.Quaternion(); | ||
| 224 : | Quaternion meshRotA = Quaternion.CreateFromAxisAngle(new Vector3(1,0,0),1.5705f); | ||
| 225 : | Quaternion meshRotB = Quaternion.CreateFromAxisAngle(new Vector3(0,1,0), 3.1415f); | ||
| 226 : | Quaternion mytemprot = _orientation * meshRotA * meshRotB; | ||
| 227 : | |||
| 228 : | myrot.W = mytemprot.W; | ||
| 229 : | myrot.X = mytemprot.X; | ||
| 230 : | myrot.Y = mytemprot.Y; | ||
| 231 : | myrot.Z = mytemprot.Z; | ||
| 232 : | d.GeomSetQuaternion(prim_geom, ref myrot); | ||
| 233 : | |||
| 234 : | if (m_isphysical && Body != IntPtr.Zero) | ||
| 235 : | { | ||
| 236 : | d.BodySetQuaternion(Body, ref myrot); | ||
| 237 : | if (!m_angularlock.IsIdentical(new PhysicsVector(1, 1, 1), 0)) | ||
| 238 : | createAMotor(m_angularlock); | ||
| 239 : | } | ||
| 240 : | |||
| 241 : | resetCollisionAccounting(); | ||
| 242 : | m_taintrot = _orientation; | ||
| 243 : | } | ||
| 244 : | |||
| 245 : | public void changesizeogremesh(float timestamp) | ||
| 246 : | { | ||
| 247 : | //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom)) | ||
| 248 : | //{ | ||
| 249 : | // m_taintsize = _size; | ||
| 250 : | //return; | ||
| 251 : | //} | ||
| 252 : | string oldname = _parent_scene.geom_name_map[prim_geom]; | ||
| 253 : | |||
| 254 : | if (_size.X <= 0) _size.X = 0.01f; | ||
| 255 : | if (_size.Y <= 0) _size.Y = 0.01f; | ||
| 256 : | if (_size.Z <= 0) _size.Z = 0.01f; | ||
| 257 : | |||
| 258 : | // Cleanup of old prim geometry | ||
| 259 : | if (_mesh != null) | ||
| 260 : | { | ||
| 261 : | // Cleanup meshing here | ||
| 262 : | } | ||
| 263 : | //kill body to rebuild | ||
| 264 : | if (IsPhysical && Body != IntPtr.Zero) | ||
| 265 : | { | ||
| 266 : | if (childPrim) | ||
| 267 : | { | ||
| 268 : | if (_parent != null) | ||
| 269 : | { | ||
| 270 : | RexOdePrim parent = (RexOdePrim)_parent; | ||
| 271 : | parent.ChildDelink(this); | ||
| 272 : | } | ||
| 273 : | } | ||
| 274 : | else | ||
| 275 : | { | ||
| 276 : | disableBody(); | ||
| 277 : | } | ||
| 278 : | } | ||
| 279 : | if (d.SpaceQuery(m_targetSpace, prim_geom)) | ||
| 280 : | { | ||
| 281 : | _parent_scene.waitForSpaceUnlock(m_targetSpace); | ||
| 282 : | d.SpaceRemove(m_targetSpace, prim_geom); | ||
| 283 : | } | ||
| 284 : | d.GeomDestroy(prim_geom); | ||
| 285 : | prim_geom = IntPtr.Zero; | ||
| 286 : | // we don't need to do space calculation because the client sends a position update also. | ||
| 287 : | |||
| 288 : | // Construction of new prim | ||
| 289 : | Mesh mesh = CreateMeshFromOriginal(); | ||
| 290 : | |||
| 291 : | CreateGeom(m_targetSpace, mesh); | ||
| 292 : | d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); | ||
| 293 : | |||
| 294 : | d.Quaternion myrot = new d.Quaternion(); | ||
| 295 : | Quaternion meshRotA = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5705f); | ||
| 296 : | Quaternion meshRotB = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 3.1415f); | ||
| 297 : | Quaternion mytemprot = _orientation * meshRotA * meshRotB; | ||
| 298 : | |||
| 299 : | myrot.W = mytemprot.W; | ||
| 300 : | myrot.X = mytemprot.X; | ||
| 301 : | myrot.Y = mytemprot.Y; | ||
| 302 : | myrot.Z = mytemprot.Z; | ||
| 303 : | d.GeomSetQuaternion(prim_geom, ref myrot); | ||
| 304 : | |||
| 305 : | //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); | ||
| 306 : | if (IsPhysical && Body == IntPtr.Zero && !childPrim) | ||
| 307 : | { | ||
| 308 : | // Re creates body on size. | ||
| 309 : | // EnableBody also does setMass() | ||
| 310 : | enableBody(); | ||
| 311 : | d.BodyEnable(Body); | ||
| 312 : | } | ||
| 313 : | |||
| 314 : | _parent_scene.geom_name_map[prim_geom] = oldname; | ||
| 315 : | |||
| 316 : | changeSelectedStatus(timestamp); | ||
| 317 : | if (childPrim) | ||
| 318 : | { | ||
| 319 : | if (_parent is OdePrim) | ||
| 320 : | { | ||
| 321 : | OdePrim parent = (OdePrim)_parent; | ||
| 322 : | parent.ChildSetGeom(this); | ||
| 323 : | } | ||
| 324 : | } | ||
| 325 : | resetCollisionAccounting(); | ||
| 326 : | m_taintsize = _size; | ||
| 327 : | m_ReCreateCollision = false; | ||
| 328 : | } | ||
| 329 : | |||
| 330 : | } | ||
| 331 : | } |
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

