}//end SetDefaultsForType internal void Enable(IntPtr pBody, AuroraODEPrim parent, AuroraODEPhysicsScene pParentScene) { if (m_enabled) return; m_enabled = true; m_previousMaterial = (Material)parent.m_material; parent.SetMaterial((int)Material.Glass); //This seems to happen in SL... and its needed for here parent.ThrottleUpdates = false; m_body = pBody; if (pBody == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) return; d.Mass mass; d.BodyGetMass(pBody, out mass); Mass = mass.mass; Mass *= 2; }
private void changelink (AuroraODEPrim newparent) { // If the newly set parent is not null // create link if (_parent == null && newparent != null) { if (newparent.PhysicsActorType == (int)ActorTypes.Prim) { AuroraODEPrim obj = (AuroraODEPrim)newparent; obj.ParentPrim (this); } } // If the newly set parent is null // destroy link else if (_parent != null && newparent == null) { //Console.WriteLine(" changelink B"); if (_parent is AuroraODEPrim) { AuroraODEPrim obj = (AuroraODEPrim)_parent; obj.ChildDelink (this); childPrim = false; //_parent = null; } } _parent = newparent; }
private void ChildSetGeom(AuroraODEPrim odePrim) { DestroyBody(); MakeBody(); }
// I'm the parent // prim is the child public void ParentPrim(AuroraODEPrim prim) { //Console.WriteLine("ParentPrim " + m_primName); if (this.m_localID != prim.m_localID) { if (Body == IntPtr.Zero) { Body = d.BodyCreate(_parent_scene.world); setMass(); } if (Body != IntPtr.Zero) { lock (childrenPrim) { if (!childrenPrim.Contains(prim)) { //Console.WriteLine("childrenPrim.Add " + prim); childrenPrim.Add(prim); foreach (AuroraODEPrim prm in childrenPrim) { d.Mass m2; d.MassSetZero(out m2); prim.Mass = prim.CalculateMass(); d.MassSetBoxTotal(out m2, prim.Mass, 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 (AuroraODEPrim prm in childrenPrim) { prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); if (prm.prim_geom == IntPtr.Zero) { m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); continue; } //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + m_primName); d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int)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.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body"); } prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; prm.m_disabled = false; // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.One, 0f)) && _parent == null) { prm.createAMotor(m_angularlock); } prm.Body = Body; _parent_scene.addActivePrim(prm); } m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + m_primName); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); //Console.WriteLine(" Post GeomSetCategoryBits 2"); d.GeomSetCollideBits(prim_geom, (int)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 if ((!m_angularlock.ApproxEquals(Vector3.One, 0f)) && _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, this, _parent_scene); _parent_scene.addActivePrim(this); } } } } }
private void ChildDelink(AuroraODEPrim odePrim) { // Okay, we have a delinked child.. need to rebuild the body. lock (childrenPrim) { foreach (AuroraODEPrim 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); } if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); } lock (childrenPrim) { foreach (AuroraODEPrim prm in childrenPrim) { //Console.WriteLine("ChildDelink calls ParentPrim"); ParentPrim(prm); } } }
public void addActivePrim(AuroraODEPrim activatePrim) { // adds active prim.. (ones that should be iterated over in collisions_optimized lock (_activeprimsLock) { if (!_activeprims.Contains(activatePrim)) _activeprims.Add(activatePrim); //else // MainConsole.Instance.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); } }
///<summary> /// This is called from within simulate but outside the locked portion /// We need to do our own locking here /// 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> public void RemovePrimThreadLocked(AuroraODEPrim prim) { //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); lock (prim) { remCollisionEventReporting(prim); remActivePrim(prim); prim.m_frozen = true; if (prim.prim_geom != IntPtr.Zero) { prim.DestroyBody(); prim.IsPhysical = false; prim.m_targetSpace = IntPtr.Zero; try { if (prim.prim_geom != IntPtr.Zero) { d.GeomDestroy(prim.prim_geom); prim.prim_geom = IntPtr.Zero; } else { MainConsole.Instance.Warn("[PHYSICS]: Unable to remove prim from physics scene"); } } catch (AccessViolationException) { MainConsole.Instance.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); } } if (!prim.childPrim) { lock (prim.childrenPrim) { foreach (AuroraODEPrim prm in prim.childrenPrim) { RemovePrimThreadLocked(prm); } } } lock (_prims) _prims.Remove(prim); } }
internal void addActivePrim(AuroraODEPrim activatePrim) { // adds active prim.. (ones that should be iterated over in collisions_optimized lock (_activeprimsLock) { if (!_activeprims.Contains(activatePrim)) _activeprims.Add(activatePrim); } }
internal void BadPrim(AuroraODEPrim auroraODEPrim) { DeletePrim(auroraODEPrim); //Can't really do this here... as it will be readded before the delete gets called, which is wrong... //So... leave the prim out there for now //AddPrimShape(auroraODEPrim.ParentEntity); }
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) { Vector3 pos = position; Vector3 siz = size; Quaternion rot = rotation; AuroraODEPrim newPrim; lock (OdeLock) { newPrim = new AuroraODEPrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); lock (_prims) _prims.Add(newPrim); } return newPrim; }
/// <summary> /// This is called from within simulate but outside the locked portion /// We need to do our own locking here /// 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> public void RemovePrimThreadLocked(AuroraODEPrim prim) { //Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); lock (prim) { remCollisionEventReporting(prim); remActivePrim(prim); lock (ode) { prim.m_frozen = true; if (prim.prim_geom != IntPtr.Zero) { prim.DestroyBody(); 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); try { if (prim.prim_geom != IntPtr.Zero) { d.GeomDestroy(prim.prim_geom); prim.prim_geom = IntPtr.Zero; } else { m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); } } catch (AccessViolationException) { m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); } 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 void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { obj2LocalID = 0; if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) return; switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: cc2 = (AuroraODECharacter)p2; switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: cc1 = (AuroraODECharacter)p1; obj2LocalID = cc1.m_localID; cc1.AddCollisionEvent(cc2.m_localID, contact); break; case ActorTypes.Prim: if (p1 is AuroraODEPrim) { cp1 = (AuroraODEPrim)p1; obj2LocalID = cp1.m_localID; cp1.AddCollisionEvent(cc2.m_localID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; break; } cc2.AddCollisionEvent(obj2LocalID, contact); break; case ActorTypes.Prim: if (p2 is AuroraODEPrim) { cp2 = (AuroraODEPrim)p2; switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: if (p1 is AuroraODECharacter) { cc1 = (AuroraODECharacter)p1; obj2LocalID = cc1.m_localID; cc1.AddCollisionEvent(cp2.m_localID, contact); } break; case ActorTypes.Prim: if (p1 is AuroraODEPrim) { cp1 = (AuroraODEPrim)p1; obj2LocalID = cp1.m_localID; cp1.AddCollisionEvent(cp2.m_localID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; break; } cp2.AddCollisionEvent(obj2LocalID, contact); } break; } }
internal void Step(IntPtr pBody, float pTimestep, AuroraODEPhysicsScene pParentScene, AuroraODEPrim parent) { m_body = pBody; if (pBody == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) return; if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); frcount++; // used to limit debug comment output if (frcount > 100) frcount = 0; MoveLinear(pTimestep, pParentScene); MoveAngular(pTimestep, pParentScene); LimitRotation(pTimestep); // WE deal with updates parent.RequestPhysicsterseUpdate(); } // end Step
internal void Disable(AuroraODEPrim parent) { if (!m_enabled) return; m_enabled = false; parent.SetMaterial((int)m_previousMaterial); //Revert to the original parent.ThrottleUpdates = true; //d.BodyDisable(Body); m_linearMotorDirection = Vector3.Zero; m_linearMotorDirectionLASTSET = Vector3.Zero; m_angularMotorDirection = Vector3.Zero; }
/// <summary> /// Called to queue a change to a prim /// to use in place of old taint mechanism so changes do have a time sequence /// </summary> public void AddChange(AuroraODEPrim prim,changes what,Object arg) { AODEchangeitem item = new AODEchangeitem(); item.prim = prim; item.what = what; item.arg = arg; // lock (ChangesQueue) { ChangesQueue.Enqueue(item); } }
/// <summary> /// Routine to figure out if we need to mesh this prim with our mesher /// </summary> /// <param name="entity"></param> /// <returns></returns> internal bool needsMeshing(AuroraODEPrim prim, byte physicalType) { PrimitiveBaseShape pbs = prim.Shape; // most of this is redundant now as the mesher will return null if it cant mesh a prim // but we still need to check for sculptie meshing being enabled so this is the most // convenient place to do it for now... // //if (pbs.PathCurve == (byte)Primitive.PathCurve.Circle && pbs.ProfileCurve == (byte)Primitive.ProfileCurve.Circle && pbs.PathScaleY <= 0.75f) // //MainConsole.Instance.Debug("needsMeshing: " + " pathCurve: " + pbs.PathCurve.ToString() + " profileCurve: " + pbs.ProfileCurve.ToString() + " pathScaleY: " + Primitive.UnpackPathScale(pbs.PathScaleY).ToString()); int iPropertiesNotSupportedDefault = 0; // return true; if (forceSimplePrimMeshing) return true; // let simple spheres use ode sphere object PrimitiveBaseShape sphere = PrimitiveBaseShape.CreateSphere(); if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.X == pbs.Scale.Z && pbs.ProfileHollow == sphere.ProfileHollow && pbs.PathBegin == sphere.PathBegin && pbs.PathEnd == sphere.PathEnd && pbs.PathCurve == sphere.PathCurve && pbs.HollowShape == sphere.HollowShape && pbs.PathRadiusOffset == sphere.PathRadiusOffset && pbs.PathRevolutions == sphere.PathRevolutions && pbs.PathScaleY == sphere.PathScaleY && pbs.PathShearX == sphere.PathShearX && pbs.PathShearY == sphere.PathShearY && pbs.PathSkew == sphere.PathSkew && pbs.PathTaperY == sphere.PathTaperY && pbs.PathTwist == sphere.PathTwist && pbs.PathTwistBegin == sphere.PathTwistBegin && pbs.ProfileBegin == sphere.ProfileBegin && pbs.ProfileEnd == sphere.ProfileEnd && pbs.ProfileHollow == sphere.ProfileHollow && pbs.ProfileShape == sphere.ProfileShape) return false; if (pbs.SculptEntry && !meshSculptedPrim) return false; else if (pbs.SculptType != (byte) SculptType.Mesh && pbs.SculptType != (byte) SculptType.None) return true; //Sculpty, mesh it else if (pbs.SculptType == (byte) SculptType.Mesh) { //Mesh, we need to see what the prims says to do with it if (physicalType == (byte) PhysicsShapeType.Prim) return false; //Supposed to be a simple box, nothing more else return true; //Mesh it! } // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim if (!forceSimplePrimMeshing) { if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte) Extrusion.Straight) /*|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)*/) { if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 && pbs.ProfileHollow == 0 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 && pbs.PathBegin == 0 && pbs.PathEnd == 0 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 && pbs.PathShearX == 0 && pbs.PathShearY == 0) { #if SPAM MainConsole.Instance.Warn("NonMesh"); #endif return false; } } } if (pbs.ProfileHollow != 0) iPropertiesNotSupportedDefault++; else if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) iPropertiesNotSupportedDefault++; else if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) iPropertiesNotSupportedDefault++; else if (pbs.PathBegin != 0 || pbs.PathEnd != 0) iPropertiesNotSupportedDefault++; else if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100)) iPropertiesNotSupportedDefault++; else if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0)) iPropertiesNotSupportedDefault++; else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte) Extrusion.Straight) iPropertiesNotSupportedDefault++; else if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X)) iPropertiesNotSupportedDefault++; else if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1) iPropertiesNotSupportedDefault++; // test for torus else if ((pbs.ProfileCurve & 0x07) == (byte) ProfileShape.Square && pbs.PathCurve == (byte) Extrusion.Curve1) iPropertiesNotSupportedDefault++; else if ((pbs.ProfileCurve & 0x07) == (byte) ProfileShape.HalfCircle && (pbs.PathCurve == (byte) Extrusion.Curve1 || pbs.PathCurve == (byte) Extrusion.Curve2)) iPropertiesNotSupportedDefault++; else if ((pbs.ProfileCurve & 0x07) == (byte) ProfileShape.EquilateralTriangle) { if (pbs.PathCurve == (byte) Extrusion.Straight) { iPropertiesNotSupportedDefault++; } else if (pbs.PathCurve == (byte) Extrusion.Curve1) { iPropertiesNotSupportedDefault++; } } if ((pbs.ProfileCurve & 0x07) == (byte) ProfileShape.Circle) { if (pbs.PathCurve == (byte) Extrusion.Straight) { iPropertiesNotSupportedDefault++; } // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits else if (pbs.PathCurve == (byte) Extrusion.Curve1) { iPropertiesNotSupportedDefault++; } } if (iPropertiesNotSupportedDefault == 0) { #if SPAM MainConsole.Instance.Warn("NonMesh"); #endif return false; } #if SPAM MainConsole.Instance.Debug("Mesh"); #endif return true; }
public override PhysicsObject AddPrimShape(ISceneChildEntity entity) { bool isPhysical = ((entity.ParentEntity.RootChild.Flags & PrimFlags.Physics) != 0); bool isPhantom = ((entity.ParentEntity.RootChild.Flags & PrimFlags.Phantom) != 0); bool physical = isPhysical & !isPhantom; /*IOpenRegionSettingsModule WSModule = entity.ParentEntity.Scene.RequestModuleInterface<IOpenRegionSettingsModule> (); if (WSModule != null) if (!WSModule.AllowPhysicalPrims) physical = false;*/ AuroraODEPrim newPrim; newPrim = new AuroraODEPrim(entity, this, false); if (physical) newPrim.IsPhysical = physical; lock (_prims) _prims.Add(newPrim); return newPrim; }
internal void remActivePrim(AuroraODEPrim deactivatePrim) { lock (_activeprimsLock) _activeprims.Remove(deactivatePrim); }
public void remActivePrim(AuroraODEPrim deactivatePrim) { lock (_activeprimsLock) { _activeprims.Remove(deactivatePrim); } }
public override PhysicsActor AddPrimShape(UUID primID, uint localID, string name, byte physicsType, PrimitiveBaseShape shape, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical) { AuroraODEPrim newPrim = new AuroraODEPrim(name, physicsType, shape, position, size, rotation, this); newPrim.UUID = primID; newPrim.LocalID = localID; if (isPhysical) newPrim.IsPhysical = isPhysical; lock (_prims) _prims.Add(newPrim); return newPrim; }
/// <summary> /// Called to queue a change to a prim /// to use in place of old taint mechanism so changes do have a time sequence /// </summary> public void AddChange(AuroraODEPrim prim, changes what, Object arg) { AODEchangeitem item = new AODEchangeitem {prim = prim, what = what, arg = arg}; ChangesQueue.Enqueue(item); }
private void SetInStaticSpace(AuroraODEPrim prm) { if (prm.m_targetSpace != null && prm.m_targetSpace == _parent_scene.space) { _parent_scene.waitForSpaceUnlock(m_targetSpace); if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); } prm.m_targetSpace = _parent_scene.calculateSpaceForGeom(prm._position); d.SpaceAdd(prm.m_targetSpace, prm.prim_geom); }
private void ChildSetGeom(AuroraODEPrim odePrim) { //if (m_isphysical && Body != IntPtr.Zero) lock (childrenPrim) { foreach (AuroraODEPrim 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(); if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); } lock (childrenPrim) { foreach (AuroraODEPrim prm in childrenPrim) { //Console.WriteLine("ChildSetGeom calls ParentPrim"); ParentPrim(prm); } } }
// I'm the parent // prim is the child public void ParentPrim(AuroraODEPrim prim) { //Console.WriteLine("ParentPrim " + m_primName); if (this.m_localID != prim.m_localID) { DestroyBody(); lock (childrenPrim) { foreach (AuroraODEPrim prm in prim.childrenPrim.Where(prm => !childrenPrim.Contains(prm))) { childrenPrim.Add(prm); } if (!childrenPrim.Contains(prim)) // must allow full reconstruction childrenPrim.Add(prim); } //Remove old children prim.childrenPrim.Clear(); prim.childPrim = true; prim._parent = this; if (prim.Body != IntPtr.Zero) { prim.DestroyBody(); // don't loose bodies around prim.Body = IntPtr.Zero; } MakeBody(); // full nasty reconstruction } }
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) { AuroraODEPrim[] childPrimArr = new AuroraODEPrim[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; }// end CalculateMass
private void changelink(AuroraODEPrim newparent) { // If the newly set parent is not null // create link if (_parent == null && newparent != null) { newparent.ParentPrim(this); } // If the newly set parent is null // destroy link else if (_parent != null) { if (_parent is AuroraODEPrim) { if (newparent != _parent) { AuroraODEPrim obj = (AuroraODEPrim) _parent; obj.ChildDelink(this); childPrim = false; if (newparent != null) { newparent.ParentPrim(this); } } } } _parent = newparent; }
// I'm the parent // prim is the child public void ParentPrim(AuroraODEPrim prim) { //Console.WriteLine("ParentPrim " + m_primName); if (this.m_localID != prim.m_localID) { lock (childrenPrim) { if (!childrenPrim.Contains(prim)) // must allow full reconstruction childrenPrim.Add(prim); } prim.childPrim = true; prim._parent = this; if (prim.Body != IntPtr.Zero && prim.Body != Body) { prim.DestroyBody(); // don't loose bodies around prim.Body = IntPtr.Zero; } if (m_isphysical) MakeBody(); // full nasty reconstruction } }
private void SetInStaticSpace(AuroraODEPrim prm) { if (prm.m_targetSpace != IntPtr.Zero && prm.m_targetSpace == _parent_scene.space) { if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); } prm.m_targetSpace = _parent_scene.calculateSpaceForGeom(prm._position); d.SpaceAdd(prm.m_targetSpace, prm.prim_geom); }
private void ChildRemove(AuroraODEPrim odePrim) { // Okay, we have a delinked child.. destroy all body and remake if (odePrim != this && !childrenPrim.Contains(odePrim)) return; DestroyBody(); if (odePrim == this) { AuroraODEPrim newroot = null; lock (childrenPrim) { if (childrenPrim.Count > 0) { newroot = childrenPrim[0]; childrenPrim.RemoveAt(0); foreach (AuroraODEPrim prm in childrenPrim) { newroot.childrenPrim.Add(prm); } childrenPrim.Clear(); } if (newroot != null) { newroot.childPrim = false; newroot._parent = null; newroot.MakeBody(); } } return; } else { lock (childrenPrim) { childrenPrim.Remove(odePrim); odePrim.childPrim = false; odePrim._parent = null; } } MakeBody(); }
///<summary> /// This is called from within simulate but outside the locked portion /// We need to do our own locking here /// 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(AuroraODEPrim prim) { remCollisionEventReporting(prim); remActivePrim(prim); prim.m_frozen = true; if (prim.prim_geom != IntPtr.Zero) { prim.DestroyBody(); prim.IsPhysical = false; prim.m_targetSpace = IntPtr.Zero; try { if (prim.prim_geom != IntPtr.Zero) { d.GeomDestroy(prim.prim_geom); prim.prim_geom = IntPtr.Zero; } else { MainConsole.Instance.Warn("[PHYSICS]: Unable to remove prim from physics scene"); } } catch (AccessViolationException) { MainConsole.Instance.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); } } if (!prim.childPrim) { lock (prim.childrenPrim) foreach (AuroraODEPrim prm in prim.childrenPrim) RemovePrimThreadLocked(prm); } if (prim.ParentEntity != null) prim.ParentEntity.PhysActor = null; //Delete it lock (_prims) _prims.Remove(prim); }