private float CalculateMass() { float volume = _size.X * _size.Y * _size.Z; // default float tmp; float returnMass = 0; float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; float hollowVolume = hollowAmount * hollowAmount; switch (_pbs.ProfileShape) { case ProfileShape.Square: // default box if (_pbs.PathCurve == (byte)Extrusion.Straight) { if (hollowAmount > 0.0) { switch (_pbs.HollowShape) { case HollowShape.Square: case HollowShape.Same: break; case HollowShape.Circle: hollowVolume *= 0.78539816339f; break; case HollowShape.Triangle: hollowVolume *= (0.5f * .5f); break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { //a tube volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY); volume -= volume*tmp*tmp; if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Square: case HollowShape.Same: break; case HollowShape.Circle: hollowVolume *= 0.78539816339f;; break; case HollowShape.Triangle: hollowVolume *= 0.5f * 0.5f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.Circle: if (_pbs.PathCurve == (byte)Extrusion.Straight) { volume *= 0.78539816339f; // elipse base if (hollowAmount > 0.0) { switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Circle: break; case HollowShape.Square: hollowVolume *= 0.5f * 2.5984480504799f; break; case HollowShape.Triangle: hollowVolume *= .5f * 1.27323954473516f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); volume *= (1.0f - tmp * tmp); if (hollowAmount > 0.0) { // calculate the hollow volume by it's shape compared to the prim shape hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Circle: break; case HollowShape.Square: hollowVolume *= 0.5f * 2.5984480504799f; break; case HollowShape.Triangle: hollowVolume *= .5f * 1.27323954473516f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.HalfCircle: if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.52359877559829887307710723054658f; } break; case ProfileShape.EquilateralTriangle: if (_pbs.PathCurve == (byte)Extrusion.Straight) { volume *= 0.32475953f; if (hollowAmount > 0.0) { // calculate the hollow volume by it's shape compared to the prim shape switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Triangle: hollowVolume *= .25f; break; case HollowShape.Square: hollowVolume *= 0.499849f * 3.07920140172638f; break; case HollowShape.Circle: // Hollow shape is a perfect cyllinder in respect to the cube's scale // Cyllinder hollow volume calculation hollowVolume *= 0.1963495f * 3.07920140172638f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.32475953f; volume *= 0.01f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); volume *= (1.0f - tmp * tmp); if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Triangle: hollowVolume *= .25f; break; case HollowShape.Square: hollowVolume *= 0.499849f * 3.07920140172638f; break; case HollowShape.Circle: hollowVolume *= 0.1963495f * 3.07920140172638f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; default: break; } float taperX1; float taperY1; float taperX; float taperY; float pathBegin; float pathEnd; float profileBegin; float profileEnd; if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) { taperX1 = _pbs.PathScaleX * 0.01f; if (taperX1 > 1.0f) taperX1 = 2.0f - taperX1; taperX = 1.0f - taperX1; taperY1 = _pbs.PathScaleY * 0.01f; if (taperY1 > 1.0f) taperY1 = 2.0f - taperY1; taperY = 1.0f - taperY1; } else { taperX = _pbs.PathTaperX * 0.01f; if (taperX < 0.0f) taperX = -taperX; taperX1 = 1.0f - taperX; taperY = _pbs.PathTaperY * 0.01f; if (taperY < 0.0f) taperY = -taperY; taperY1 = 1.0f - taperY; } volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); pathBegin = (float)_pbs.PathBegin * 2.0e-5f; pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; volume *= (pathEnd - pathBegin); // this is crude aproximation profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; volume *= (profileEnd - profileBegin); returnMass = m_density * volume; if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. // else if (returnMass > _parent_scene.maximumMassObject) // returnMass = _parent_scene.maximumMassObject; // Recursively calculate mass bool HasChildPrim = false; lock (childrenPrim) { if (childrenPrim.Count > 0) { HasChildPrim = true; } } if (HasChildPrim) { OdePrim[] childPrimArr = new OdePrim[0]; lock (childrenPrim) childPrimArr = childrenPrim.ToArray(); for (int i = 0; i < childPrimArr.Length; i++) { if (childPrimArr[i] != null && !childPrimArr[i].m_taintremove) returnMass += childPrimArr[i].CalculateMass(); // failsafe, this shouldn't happen but with OpenSim, you never know :) if (i > 256) break; } } if (returnMass > _parent_scene.maximumMassObject) returnMass = _parent_scene.maximumMassObject; return returnMass; }
private void ChildSetGeom(OdePrim odePrim) { // m_log.DebugFormat( // "[ODE PRIM]: ChildSetGeom {0} {1} for {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID); //if (IsPhysical && Body != IntPtr.Zero) lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) { //prm.childPrim = true; prm.disableBody(); //prm.m_taintparent = null; //prm._parent = null; //prm.m_taintPhysics = false; //prm.m_disabled = true; //prm.childPrim = false; } } disableBody(); // Spurious - Body == IntPtr.Zero after disableBody() // if (Body != IntPtr.Zero) // { // _parent_scene.DeactivatePrim(this); // } lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) { //Console.WriteLine("ChildSetGeom calls ParentPrim"); AddChildPrim(prm); } } }
private void ChildDelink(OdePrim odePrim) { // m_log.DebugFormat( // "[ODE PRIM]: Delinking prim {0} {1} from {2} {3}", odePrim.Name, odePrim.LocalID, Name, LocalID); // Okay, we have a delinked child.. need to rebuild the body. lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) { prm.childPrim = true; prm.disableBody(); //prm.m_taintparent = null; //prm._parent = null; //prm.m_taintPhysics = false; //prm.m_disabled = true; //prm.childPrim = false; } } disableBody(); lock (childrenPrim) { //Console.WriteLine("childrenPrim.Remove " + odePrim); childrenPrim.Remove(odePrim); } // Spurious - Body == IntPtr.Zero after disableBody() // if (Body != IntPtr.Zero) // { // _parent_scene.DeactivatePrim(this); // } lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) { //Console.WriteLine("ChildDelink calls ParentPrim"); AddChildPrim(prm); } } }
/// <summary> /// Simulate the joint proxies of a NINJA actor. /// </summary> /// <remarks> /// Called as part of the Simulate() loop if NINJA physics is active. Must only be called from there. /// </remarks> /// <param name="actor"></param> private void SimulateActorPendingJoints(OdePrim actor) { // If an actor moved, move its joint proxy objects as well. // There seems to be an event PhysicsActor.OnPositionUpdate that could be used // for this purpose but it is never called! So we just do the joint // movement code here. if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null && joints_connecting_actor[actor.SOPName].Count > 0) { foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) { if (affectedJoint.IsInPhysicsEngine) { DoJointMoved(affectedJoint); } else { DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); } } } }
/// <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); } }
/// <summary> /// Stop this prim being subject to physics /// </summary> /// <param name="prim"></param> internal void DeactivatePrim(OdePrim prim) { _activeprims.Remove(prim); }
/// <summary> /// This is called from within simulate but outside the locked portion /// We need to do our own locking here /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in /// Simulate() -- justincc). /// /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. /// /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory /// that the space was using. /// </summary> /// <param name="prim"></param> internal void RemovePrimThreadLocked(OdePrim prim) { // m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID); lock (prim) { RemoveCollisionEventReporting(prim); if (prim.prim_geom != IntPtr.Zero) { prim.ResetTaints(); if (prim.IsPhysical) { prim.disableBody(); if (prim.childPrim) { prim.childPrim = false; prim.Body = IntPtr.Zero; prim.m_disabled = true; prim.IsPhysical = false; } } // we don't want to remove the main space // If the geometry is in the targetspace, remove it from the target space //m_log.Warn(prim.m_targetSpace); //if (prim.m_targetSpace != IntPtr.Zero) //{ //if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom)) //{ //if (d.GeomIsSpace(prim.m_targetSpace)) //{ //waitForSpaceUnlock(prim.m_targetSpace); //d.SpaceRemove(prim.m_targetSpace, prim.prim_geom); prim.m_targetSpace = IntPtr.Zero; //} //else //{ // m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + //((OdePrim)prim).m_targetSpace.ToString()); //} //} //} //m_log.Warn(prim.prim_geom); if (!prim.RemoveGeom()) m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene"); lock (_prims) _prims.Remove(prim); //If there are no more geometries in the sub-space, we don't need it in the main space anymore //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) //{ //if (prim.m_targetSpace != null) //{ //if (d.GeomIsSpace(prim.m_targetSpace)) //{ //waitForSpaceUnlock(prim.m_targetSpace); //d.SpaceRemove(space, prim.m_targetSpace); // free up memory used by the space. //d.SpaceDestroy(prim.m_targetSpace); //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position); //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]); //} //else //{ //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + //((OdePrim) prim).m_targetSpace.ToString()); //} //} //} if (SupportsNINJAJoints) RemoveAllJointsConnectedToActorThreadLocked(prim); } } }
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, PrimitiveBaseShape pbs, bool isphysical, uint localID) { Vector3 pos = position; Vector3 siz = size; Quaternion rot = rotation; OdePrim newPrim; lock (OdeLock) { newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical); lock (_prims) _prims.Add(newPrim); } newPrim.LocalID = localID; return newPrim; }
/// <summary> /// Make this prim subject to physics. /// </summary> /// <param name="prim"></param> internal void ActivatePrim(OdePrim prim) { // adds active prim.. (ones that should be iterated over in collisions_optimized if (!_activeprims.Contains(prim)) _activeprims.Add(prim); //else // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); }
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { // obj1LocalID = 0; //returncollisions = false; obj2LocalID = 0; //ctype = 0; //cStartStop = 0; if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) return; switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: cc2 = (OdeCharacter)p2; // obj1LocalID = cc2.m_localID; switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: cc1 = (OdeCharacter)p1; obj2LocalID = cc1.LocalID; cc1.AddCollisionEvent(cc2.LocalID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.LocalID; cp1.AddCollisionEvent(cc2.LocalID, contact); } //ctype = (int)CollisionCategories.Geom; //if (cp1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; //ctype = (int)CollisionCategories.Land; //returncollisions = true; break; } cc2.AddCollisionEvent(obj2LocalID, contact); break; case ActorTypes.Prim: if (p2 is OdePrim) { cp2 = (OdePrim) p2; // obj1LocalID = cp2.m_localID; switch ((ActorTypes) p1.PhysicsActorType) { case ActorTypes.Agent: if (p1 is OdeCharacter) { cc1 = (OdeCharacter) p1; obj2LocalID = cc1.LocalID; cc1.AddCollisionEvent(cp2.LocalID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; } break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.LocalID; cp1.AddCollisionEvent(cp2.LocalID, contact); //ctype = (int)CollisionCategories.Geom; //if (cp1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; //ctype = (int)CollisionCategories.Land; //returncollisions = true; break; } cp2.AddCollisionEvent(obj2LocalID, contact); } break; } //if (returncollisions) //{ //lock (m_storedCollisions) //{ //cDictKey = obj1LocalID.ToString() + obj2LocalID.ToString() + cStartStop.ToString() + ctype.ToString(); //if (m_storedCollisions.ContainsKey(cDictKey)) //{ //sCollisionData objd = m_storedCollisions[cDictKey]; //objd.NumberOfCollisions += 1; //objd.lastframe = framecount; //m_storedCollisions[cDictKey] = objd; //} //else //{ //sCollisionData objd = new sCollisionData(); //objd.ColliderLocalId = obj1LocalID; //objd.CollidedWithLocalId = obj2LocalID; //objd.CollisionType = ctype; //objd.NumberOfCollisions = 1; //objd.lastframe = framecount; //objd.StatusIndicator = cStartStop; //m_storedCollisions.Add(cDictKey, objd); //} //} // } }
/// <summary> /// This is called from within simulate but outside the locked portion /// We need to do our own locking here /// (Note: As of 20110801 this no longer appears to be true - this is being called within lock (odeLock) in /// Simulate() -- justincc). /// /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. /// /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory /// that the space was using. /// </summary> /// <param name="prim"></param> internal void RemovePrimThreadLocked(OdePrim prim) { // m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID); lock (prim) { RemoveCollisionEventReporting(prim); if (prim.prim_geom != IntPtr.Zero) { prim.ResetTaints(); if (prim.IsPhysical) { prim.disableBody(); if (prim.childPrim) { prim.childPrim = false; prim.Body = IntPtr.Zero; prim.m_disabled = true; prim.IsPhysical = false; } } prim.m_targetSpace = IntPtr.Zero; if (!prim.RemoveGeom()) m_log.Warn("[ODE SCENE]: Unable to remove prim from physics scene"); lock (_prims) _prims.Remove(prim); if (SupportsNINJAJoints) RemoveAllJointsConnectedToActorThreadLocked(prim); } } }
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { // obj1LocalID = 0; //returncollisions = false; obj2LocalID = 0; //ctype = 0; //cStartStop = 0; // if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) // return; bool p1events = p1.SubscribedEvents(); bool p2events = p2.SubscribedEvents(); if (p1.IsVolumeDtc) p2events = false; if (p2.IsVolumeDtc) p1events = false; if (!p2events && !p1events) return; Vector3 vel = Vector3.Zero; if (p2 != null && p2.IsPhysical) vel = p2.Velocity; if (p1 != null && p1.IsPhysical) vel -= p1.Velocity; contact.RelativeSpeed = Vector3.Dot(vel, contact.SurfaceNormal); switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: cc2 = (OdeCharacter)p2; // obj1LocalID = cc2.m_localID; switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: cc1 = (OdeCharacter)p1; obj2LocalID = cc1.LocalID; cc1.AddCollisionEvent(cc2.LocalID, contact); break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.LocalID; cp1.AddCollisionEvent(cc2.LocalID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; break; } cc2.AddCollisionEvent(obj2LocalID, contact); break; case ActorTypes.Prim: if (p2 is OdePrim) { cp2 = (OdePrim) p2; // obj1LocalID = cp2.m_localID; switch ((ActorTypes) p1.PhysicsActorType) { case ActorTypes.Agent: if (p1 is OdeCharacter) { cc1 = (OdeCharacter) p1; obj2LocalID = cc1.LocalID; cc1.AddCollisionEvent(cp2.LocalID, contact); } break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.LocalID; cp1.AddCollisionEvent(cp2.LocalID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; break; } cp2.AddCollisionEvent(obj2LocalID, contact); } break; } }
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { // obj1LocalID = 0; //returncollisions = false; obj2LocalID = 0; //ctype = 0; //cStartStop = 0; if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) return; switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: cc2 = (OdeCharacter)p2; // obj1LocalID = cc2.m_localID; switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: cc1 = (OdeCharacter)p1; obj2LocalID = cc1.LocalID; cc1.AddCollisionEvent(cc2.LocalID, contact); break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.LocalID; cp1.AddCollisionEvent(cc2.LocalID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; break; } cc2.AddCollisionEvent(obj2LocalID, contact); break; case ActorTypes.Prim: if (p2 is OdePrim) { cp2 = (OdePrim) p2; // obj1LocalID = cp2.m_localID; switch ((ActorTypes) p1.PhysicsActorType) { case ActorTypes.Agent: if (p1 is OdeCharacter) { cc1 = (OdeCharacter) p1; obj2LocalID = cc1.LocalID; cc1.AddCollisionEvent(cp2.LocalID, contact); } break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.LocalID; cp1.AddCollisionEvent(cp2.LocalID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; break; } cp2.AddCollisionEvent(obj2LocalID, contact); } break; } }