/// <summary> /// Change prim in response to a shape taint. /// </summary> private void changeshape() { m_taintshape = false; // Cleanup of old prim geometry and Bodies if (IsPhysical && Body != IntPtr.Zero) { if (childPrim) { if (_parent != null) { OdePrim parent = (OdePrim)_parent; parent.ChildDelink(this); } } else { disableBody(); } } RemoveGeom(); // we don't need to do space calculation because the client sends a position update also. if (_size.X <= 0) _size.X = 0.01f; if (_size.Y <= 0) _size.Y = 0.01f; if (_size.Z <= 0) _size.Z = 0.01f; // Construction of new prim IMesh mesh = null; if (_parent_scene.needsMeshing(_pbs)) { // Don't need to re-enable body.. it's done in CreateMesh float meshlod = _parent_scene.meshSculptLOD; if (IsPhysical) meshlod = _parent_scene.MeshSculptphysicalLOD; // createmesh returns null when it doesn't mesh. mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); if (mesh == null) CheckMeshAsset(); else m_assetFailed = false; } CreateGeom(m_targetSpace, mesh); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); //myrot.W = _orientation.w; myrot.W = _orientation.W; myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; d.GeomSetQuaternion(prim_geom, ref myrot); //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); if (IsPhysical && Body == IntPtr.Zero) { // Re creates body on size. // EnableBody also does setMass() enableBody(); if (Body != IntPtr.Zero) { d.BodyEnable(Body); } } changeSelectedStatus(); if (childPrim) { if (_parent is OdePrim) { OdePrim parent = (OdePrim)_parent; parent.ChildSetGeom(this); } } resetCollisionAccounting(); // m_taintshape = false; }
/// <summary> /// Make a prim subject to physics. /// </summary> private void enableBody() { // Don't enable this body if we're a child prim // this should be taken care of in the parent function not here if (!childPrim) { // Sets the geom to a body Body = d.BodyCreate(_parent_scene.world); setMass(); d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.BodySetQuaternion(Body, ref myrot); d.GeomSetBody(prim_geom, Body); if (m_assetFailed) { d.GeomSetCategoryBits(prim_geom, 0); d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); } else { m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); } d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); // disconnect from world gravity so we can apply buoyancy d.BodySetGravityMode (Body, false); m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; // The body doesn't already have a finite rotation mode set here if (m_angularlock != 0 && _parent == null) { createAMotor(m_angularlock); } if (m_vehicle.Type != Vehicle.TYPE_NONE) { m_vehicle.Enable(Body, _parent_scene); } _parent_scene.ActivatePrim(this); } }
/// <summary> /// Change prim in response to a size taint. /// </summary> private void changesize() { #if SPAM m_log.DebugFormat("[ODE PRIM]: Called changesize"); #endif if (_size.X <= 0) _size.X = 0.01f; if (_size.Y <= 0) _size.Y = 0.01f; if (_size.Z <= 0) _size.Z = 0.01f; //kill body to rebuild if (IsPhysical && Body != IntPtr.Zero) { if (childPrim) { if (_parent != null) { OdePrim parent = (OdePrim)_parent; parent.ChildDelink(this); } } else { disableBody(); } } if (d.SpaceQuery(m_targetSpace, prim_geom)) { // _parent_scene.waitForSpaceUnlock(m_targetSpace); d.SpaceRemove(m_targetSpace, prim_geom); } RemoveGeom(); // we don't need to do space calculation because the client sends a position update also. IMesh mesh = null; // Construction of new prim if (_parent_scene.needsMeshing(_pbs)) { float meshlod = _parent_scene.meshSculptLOD; if (IsPhysical) meshlod = _parent_scene.MeshSculptphysicalLOD; // Don't need to re-enable body.. it's done in SetMesh if (_parent_scene.needsMeshing(_pbs)) { mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, meshlod, IsPhysical); if (mesh == null) CheckMeshAsset(); else m_assetFailed = false; } } CreateGeom(m_targetSpace, mesh); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.GeomSetQuaternion(prim_geom, ref myrot); //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); if (IsPhysical && Body == IntPtr.Zero && !childPrim) { // Re creates body on size. // EnableBody also does setMass() enableBody(); d.BodyEnable(Body); } changeSelectedStatus(); if (childPrim) { if (_parent is OdePrim) { OdePrim parent = (OdePrim)_parent; parent.ChildSetGeom(this); } } resetCollisionAccounting(); m_taintsize = _size; }
private void rotate() { d.Quaternion myrot = new d.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; if (Body != IntPtr.Zero) { // KF: If this is a root prim do BodySet d.BodySetQuaternion(Body, ref myrot); if (IsPhysical) { // create or remove locks createAMotor(m_angularlock); } } else { // daughter prim, do Geom set d.GeomSetQuaternion(prim_geom, ref myrot); } resetCollisionAccounting(); m_taintrot = _orientation; }
/// <summary> /// Add prim in response to an add taint. /// </summary> private void changeadd() { // m_log.DebugFormat("[ODE PRIM]: Adding prim {0}", Name); int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position); if (targetspace == IntPtr.Zero) targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]); m_targetSpace = targetspace; IMesh mesh = null; if (_parent_scene.needsMeshing(_pbs)) { // Don't need to re-enable body.. it's done in SetMesh mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); // createmesh returns null when it's a shape that isn't a cube. // m_log.Debug(m_localID); if (mesh == null) CheckMeshAsset(); else m_assetFailed = false; } #if SPAM Console.WriteLine("changeadd 1"); #endif CreateGeom(m_targetSpace, mesh); d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.GeomSetQuaternion(prim_geom, ref myrot); if (IsPhysical && Body == IntPtr.Zero) enableBody(); changeSelectedStatus(); m_taintadd = false; }
/// <summary> /// Add a child prim to this parent prim. /// </summary> /// <param name="prim">Child prim</param> private void AddChildPrim(OdePrim prim) { if (LocalID == prim.LocalID) return; if (Body == IntPtr.Zero) { Body = d.BodyCreate(_parent_scene.world); setMass(); } lock (childrenPrim) { if (childrenPrim.Contains(prim)) return; // m_log.DebugFormat( // "[ODE PRIM]: Linking prim {0} {1} to {2} {3}", prim.Name, prim.LocalID, Name, LocalID); childrenPrim.Add(prim); foreach (OdePrim prm in childrenPrim) { d.Mass m2; d.MassSetZero(out m2); d.MassSetBoxTotal(out m2, prm.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); d.MassRotate(ref m2, ref mat); d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); d.MassAdd(ref pMass, ref m2); } foreach (OdePrim prm in childrenPrim) { prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); if (prm.m_assetFailed) { d.GeomSetCategoryBits(prm.prim_geom, 0); d.GeomSetCollideBits(prm.prim_geom, (uint)prm.BadMeshAssetCollideBits); } else { d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); } d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); if (Body != IntPtr.Zero) { d.GeomSetBody(prm.prim_geom, Body); prm.childPrim = true; d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); } else { m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name); } prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; prm.m_disabled = false; prm.Body = Body; _parent_scene.ActivatePrim(prm); } m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); if (m_assetFailed) { d.GeomSetCategoryBits(prim_geom, 0); d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); } else { //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); //Console.WriteLine(" Post GeomSetCategoryBits 2"); d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } d.Quaternion quat2 = new d.Quaternion(); quat2.W = _orientation.W; quat2.X = _orientation.X; quat2.Y = _orientation.Y; quat2.Z = _orientation.Z; d.Matrix3 mat2 = new d.Matrix3(); d.RfromQ(out mat2, ref quat2); d.GeomSetBody(prim_geom, Body); d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); //d.GeomSetOffsetRotation(prim_geom, ref mat2); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; // The body doesn't already have a finite rotation mode set here // or remove if (_parent == null) { createAMotor(m_angularlock); } d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); _parent_scene.ActivatePrim(this); } }
} //end MoveAngular internal void LimitRotation(float timestep) { d.Quaternion rot = d.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object d.Quaternion m_rot = new d.Quaternion(); bool changed = false; m_rot.X = rotq.X; m_rot.Y = rotq.Y; m_rot.Z = rotq.Z; m_rot.W = rotq.W; if (m_RollreferenceFrame != Quaternion.Identity) { if (rotq.X >= m_RollreferenceFrame.X) { m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); } if (rotq.Y >= m_RollreferenceFrame.Y) { m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); } if (rotq.X <= -m_RollreferenceFrame.X) { m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); } if (rotq.Y <= -m_RollreferenceFrame.Y) { m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); } changed = true; } if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) { m_rot.X = 0; m_rot.Y = 0; changed = true; } if (changed) d.BodySetQuaternion(Body, ref m_rot); }