public override void RemoveAvatar(PhysicsActor actor) { BasicActor act = (BasicActor) actor; if (_actors.Contains(act)) { _actors.Remove(act); } }
public override void RemovePrim(PhysicsActor prim) { POSPrim p = (POSPrim) prim; if (_prims.Contains(p)) { _prims.Remove(p); } }
public override void RemoveAvatar(PhysicsActor character) { POSCharacter act = (POSCharacter) character; if (_characters.Contains(act)) { _characters.Remove(act); } }
/// <summary> /// Indicates that an actor has been updated by the engine. /// NOTE: This is an override method that is not needed. /// </summary> /// <param name="prim">The actor that was modified</param> public override void AddPhysicsActorTaint(PhysicsActor prim) { // Nothing to do here }
public override void RemoveAvatar(PhysicsActor actor) { this.QueueCommand(new Commands.RemoveCharacterCmd((PhysxCharacter)actor)); }
public override void link(PhysicsActor obj) { return; }
/// <summary> /// Remove an avatar. /// </summary> /// <param name="actor"></param> public abstract void RemoveAvatar(PhysicsActor actor);
/// <summary> /// Apply physics to this part. /// </summary> /// <param name="rootObjectFlags"></param> /// <param name="m_physicalPrim"></param> public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool m_physicalPrim) { bool isPhysical = (((rootObjectFlags & (uint) PrimFlags.Physics) != 0) && m_physicalPrim); bool isPhantom = ((rootObjectFlags & (uint) PrimFlags.Phantom) != 0); if (IsJoint()) { DoPhysicsPropertyUpdate(isPhysical, true); } else { // Special case for VolumeDetection: If VolumeDetection is set, the phantom flag is locally ignored if (VolumeDetectActive) isPhantom = false; // Added clarification.. since A rigid body is an object that you can kick around, etc. bool RigidBody = isPhysical && !isPhantom; // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition // or flexible if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) { PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( Name, Shape, AbsolutePosition, Scale, RotationOffset, RigidBody); // Basic Physics returns null.. joy joy joy. if (PhysActor != null) { PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info PhysActor.SOPDescription = this.Description; PhysActor.LocalID = LocalId; DoPhysicsPropertyUpdate(RigidBody, true); PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0); } } } }
public void AttachToPhysicsShape(PhysicsActor shape, bool isChild) { PhysActor = shape; SetPhysActorRelationProperties(); if (!isChild) { PhysActor.OnRequestTerseUpdate -= this.PhysicsRequestingTerseUpdate; PhysActor.OnRequestTerseUpdate += this.PhysicsRequestingTerseUpdate; PhysActor.OnComplexityError -= new PhysicsActor.ComplexityError(PhysActor_OnComplexityError); PhysActor.OnComplexityError += new PhysicsActor.ComplexityError(PhysActor_OnComplexityError); PhysActor.OnPhysicsRequestingOBB -= PhysActor_OnPhysicsRequestingOBB; PhysActor.OnPhysicsRequestingOBB += PhysActor_OnPhysicsRequestingOBB; } PhysActor.OnNeedsPersistence -= new PhysicsActor.RequestPersistence(PhysActor_OnNeedsPersistence); PhysActor.OnNeedsPersistence += new PhysicsActor.RequestPersistence(PhysActor_OnNeedsPersistence); PhysActor.OnPositionUpdate -= new PositionUpdate(PhysActor_OnPositionUpdate); PhysActor.OnPositionUpdate += new PositionUpdate(PhysActor_OnPositionUpdate); this.CheckForScriptCollisionEventsAndSubscribe(); }
public abstract void link(PhysicsActor obj);
public void GetMesh(ODEPhysRepData repData) { PhysicsActor actor = repData.actor; PrimitiveBaseShape pbs = repData.pbs; repData.mesh = null; repData.hasOBB = false; if (!needsMeshing(repData)) { repData.meshState = MeshState.noNeed; return; } if (repData.meshState == MeshState.MeshFailed) { return; } if (pbs.SculptEntry) { if (repData.meshState == MeshState.AssetFailed) { if (pbs.SculptTexture == repData.assetID) { return; } } } repData.meshState = MeshState.noNeed; IMesh mesh = null; Vector3 size = repData.size; byte shapetype = repData.shapetype; bool convex; int clod = (int)LevelOfDetail.High; if (shapetype == 0) { convex = false; } else { convex = true; if (pbs.SculptType != (byte)SculptType.Mesh) { clod = (int)LevelOfDetail.Low; } } mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); if (mesh == null) { if (pbs.SculptEntry) { if (pbs.SculptTexture == UUID.Zero) { return; } repData.assetID = pbs.SculptTexture; if (pbs.SculptData == null || pbs.SculptData.Length == 0) { repData.meshState = MeshState.needAsset; return; } } } repData.mesh = mesh; repData.pbs.SculptData = Utils.EmptyBytes; if (mesh == null) { if (pbs.SculptEntry) { repData.meshState = MeshState.AssetFailed; } else { repData.meshState = MeshState.MeshFailed; } return; } repData.meshState = MeshState.AssetOK; return; }
// see if we need a mesh and if so if we have a cached one // called with a new repData public void CheckMesh(ODEPhysRepData repData) { PhysicsActor actor = repData.actor; PrimitiveBaseShape pbs = repData.pbs; if (!needsMeshing(repData)) { repData.meshState = MeshState.noNeed; repData.hasOBB = false; return; } IMesh mesh = null; Vector3 size = repData.size; int clod = (int)LevelOfDetail.High; byte shapetype = repData.shapetype; bool convex = shapetype == 2; mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); if (mesh == null) { if (pbs.SculptEntry) { if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero) { repData.assetID = pbs.SculptTexture; repData.meshState = MeshState.needAsset; } else { repData.meshState = MeshState.MeshFailed; } return; } else { repData.meshState = MeshState.needMesh; mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); if (mesh == null) { repData.meshState = MeshState.MeshFailed; return; } } } repData.meshState = MeshState.AssetOK; repData.mesh = mesh; repData.OBB = mesh.GetOBB(); repData.OBBOffset = mesh.GetCentroid(); repData.hasOBB = true; if (pbs.SculptEntry) { repData.assetID = pbs.SculptTexture; } pbs.SculptData = Utils.EmptyBytes; return; }
public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local) { if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) { return; } bool pushAllowed = false; bool pusheeIsAvatar = false; UUID targetID = UUID.Zero; if (!UUID.TryParse(target, out targetID)) { return; } IScenePresence pusheeav = null; Vector3 PusheePos = Vector3.Zero; ISceneChildEntity pusheeob = null; IScenePresence avatar = World.GetScenePresence(targetID); if (avatar != null) { pusheeIsAvatar = true; // Pushee is in GodMode this pushing object isn't owned by them if (avatar.GodLevel > 0 && m_host.OwnerID != targetID) { return; } pusheeav = avatar; // Find pushee position // Pushee Linked? if (pusheeav.ParentID != UUID.Zero) { ISceneChildEntity parentobj = World.GetSceneObjectPart(pusheeav.ParentID); PusheePos = parentobj != null ? parentobj.AbsolutePosition : pusheeav.AbsolutePosition; } else { PusheePos = pusheeav.AbsolutePosition; } } if (!pusheeIsAvatar) { // not an avatar so push is not affected by parcel flags pusheeob = World.GetSceneObjectPart(UUID.Parse(target)); // We can't find object if (pusheeob == null) { return; } // Object not pushable. Not an attachment and has no physics component if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) { return; } PusheePos = pusheeob.AbsolutePosition; pushAllowed = true; } else { IParcelManagementModule parcelManagement = World.RequestModuleInterface <IParcelManagementModule>(); if (World.RegionInfo.RegionSettings.RestrictPushing) { pushAllowed = m_host.OwnerID == targetID || m_host.ParentEntity.Scene.Permissions.IsGod(m_host.OwnerID); } else { if (parcelManagement != null) { ILandObject targetlandObj = parcelManagement.GetLandObject(PusheePos.X, PusheePos.Y); if (targetlandObj == null) { // We didn't find the parcel but region isn't push restricted so assume it's ok pushAllowed = true; } else { // Parcel push restriction pushAllowed = (targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) != (uint)ParcelFlags.RestrictPushObject || m_host.ParentEntity.Scene.Permissions.CanPushObject(m_host.OwnerID, targetlandObj); } } } } if (pushAllowed) { float distance = (PusheePos - m_host.AbsolutePosition).Length(); float distance_term = distance * distance * distance; // Script Energy float pusher_mass = m_host.GetMass(); const float PUSH_ATTENUATION_DISTANCE = 17f; const float PUSH_ATTENUATION_SCALE = 5f; float distance_attenuation = 1f; if (distance > PUSH_ATTENUATION_DISTANCE) { float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE; distance_attenuation = 1f / normalized_units; } Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z); { float impulse_length = applied_linear_impulse.Length(); float desired_energy = impulse_length * pusher_mass; if (desired_energy > 0f) { desired_energy += distance_term; } float scaling_factor = 1f; scaling_factor *= distance_attenuation; applied_linear_impulse *= scaling_factor; } if (pusheeIsAvatar) { if (pusheeav != null) { PhysicsActor pa = pusheeav.PhysicsActor; if (pa != null) { if (local != 0) { applied_linear_impulse *= m_host.GetWorldRotation(); } //Put a limit on it... int MaxPush = (int)pusheeav.PhysicsActor.Mass * 25; if (applied_linear_impulse.X > 0 && Math.Abs(applied_linear_impulse.X) > MaxPush) { applied_linear_impulse.X = MaxPush; } if (applied_linear_impulse.X < 0 && Math.Abs(applied_linear_impulse.X) > MaxPush) { applied_linear_impulse.X = -MaxPush; } if (applied_linear_impulse.Y > 0 && Math.Abs(applied_linear_impulse.X) > MaxPush) { applied_linear_impulse.Y = MaxPush; } if (applied_linear_impulse.Y < 0 && Math.Abs(applied_linear_impulse.Y) > MaxPush) { applied_linear_impulse.Y = -MaxPush; } if (applied_linear_impulse.Z > 0 && Math.Abs(applied_linear_impulse.X) > MaxPush) { applied_linear_impulse.Z = MaxPush; } if (applied_linear_impulse.Z < 0 && Math.Abs(applied_linear_impulse.Z) > MaxPush) { applied_linear_impulse.Z = -MaxPush; } pa.AddForce(applied_linear_impulse, true); } } } else { if (pusheeob.PhysActor != null) { pusheeob.ApplyImpulse(applied_linear_impulse, local != 0); } } } }
/// <summary> /// This method determines the proper movement related animation /// </summary> private string DetermineMovementAnimation() { const int FALL_DELAY = 800; const int PREJUMP_DELAY = 200; const int JUMP_PERIOD = 800; #region Inputs if (m_scenePresence.IsInTransit) { return(CurrentMovementAnimation); } if (m_scenePresence.SitGround) { currentControlState = motionControlStates.sitted; return("SITGROUND"); } if (m_scenePresence.ParentID != 0 || m_scenePresence.ParentUUID != UUID.Zero) { currentControlState = motionControlStates.sitted; return("SIT"); } AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; PhysicsActor actor = m_scenePresence.PhysicsActor; const AgentManager.ControlFlags ANYXYMASK = ( AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG ); // Check control flags /* not in use * bool heldForward = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)) != 0); * bool heldBack = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG)) != 0); * bool heldLeft = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)) != 0); * bool heldRight = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)) != 0); */ bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; // bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS)) != 0); // excluded nudge up so it doesn't trigger jump state bool heldUp = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS)) != 0); bool heldDown = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG)) != 0); //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK; bool heldOnXY = ((controlFlags & ANYXYMASK) != 0); if (heldOnXY || heldUp || heldDown) { heldTurnLeft = false; heldTurnRight = false; } #endregion Inputs // no physics actor case if (actor == null) { // well what to do? currentControlState = motionControlStates.onsurface; if (heldOnXY) { return("WALK"); } return("STAND"); } #region Flying bool isColliding = actor.IsColliding; if (actor.Flying) { m_animTickFall = 0; m_animTickJump = 0; m_jumping = false; Falling = false; currentControlState = motionControlStates.flying; if (heldOnXY) { return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY"); } else if (heldUp) { return("HOVER_UP"); } else if (heldDown) { if (isColliding) { actor.Flying = false; currentControlState = motionControlStates.landing; m_animTickLand = Environment.TickCount; return("LAND"); } else { return("HOVER_DOWN"); } } else { return("HOVER"); } } else { if (isColliding && currentControlState == motionControlStates.flying) { currentControlState = motionControlStates.landing; m_animTickLand = Environment.TickCount; return("LAND"); } } #endregion Flying #region Falling/Floating/Landing if (!isColliding && currentControlState != motionControlStates.jumping) { float fallVelocity = actor.Velocity.Z; // if stable on Hover assume falling if (actor.PIDHoverActive && fallVelocity < 0.05f) { Falling = true; currentControlState = motionControlStates.falling; m_lastFallVelocity = fallVelocity; return("FALLDOWN"); } if (fallVelocity < -2.5f) { Falling = true; } if (m_animTickFall == 0 || (fallVelocity >= -0.5f)) { m_animTickFall = Environment.TickCount; } else { int fallElapsed = (Environment.TickCount - m_animTickFall); if ((fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f)) { currentControlState = motionControlStates.falling; m_lastFallVelocity = fallVelocity; // Falling long enough to trigger the animation return("FALLDOWN"); } } // Check if the user has stopped walking just now if (CurrentMovementAnimation == "WALK" && !heldOnXY && !heldDown && !heldUp) { return("STAND"); } return(CurrentMovementAnimation); } m_animTickFall = 0; #endregion Falling/Floating/Landing #region Jumping // section added for jumping... if (isColliding && heldUp && currentControlState != motionControlStates.jumping && !actor.PIDHoverActive) { // Start jumping, prejump currentControlState = motionControlStates.jumping; m_jumping = true; Falling = false; m_animTickJump = Environment.TickCount; return("PREJUMP"); } if (currentControlState == motionControlStates.jumping) { int jumptime = Environment.TickCount - m_animTickJump; if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding) { // end jumping m_jumping = false; Falling = false; actor.Selected = false; // borrowed for jumping flag m_animTickLand = Environment.TickCount; currentControlState = motionControlStates.landing; return("LAND"); } else if (jumptime > JUMP_PERIOD) { // jump down return("JUMP"); } else if (jumptime > PREJUMP_DELAY) { // jump up m_jumping = true; return("JUMP"); } return(CurrentMovementAnimation); } #endregion Jumping #region Ground Movement if (currentControlState == motionControlStates.falling) { Falling = false; currentControlState = motionControlStates.landing; m_animTickLand = Environment.TickCount; // TODO: SOFT_LAND support float fallVsq = m_lastFallVelocity * m_lastFallVelocity; if (fallVsq > 300f) // aprox 20*h { return("STANDUP"); } else if (fallVsq > 160f) { return("SOFT_LAND"); } else { return("LAND"); } } if (currentControlState == motionControlStates.landing) { Falling = false; int landElapsed = Environment.TickCount - m_animTickLand; int limit = 1000; if (CurrentMovementAnimation == "LAND") { limit = 350; } // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client if ((m_animTickLand != 0) && (landElapsed <= limit)) { return(CurrentMovementAnimation); } else { currentControlState = motionControlStates.onsurface; m_animTickLand = 0; return("STAND"); } } // next section moved outside paren. and realigned for jumping if (heldOnXY) { currentControlState = motionControlStates.onsurface; Falling = false; // Walking / crouchwalking / running if (heldDown) { return("CROUCHWALK"); } // We need to prevent these animations if the user tries to make their avatar walk or run whilst // specifying AGENT_CONTROL_STOP (pressing down space on viewers). else if (!m_scenePresence.AgentControlStopActive) { if (m_scenePresence.SetAlwaysRun) { return("RUN"); } else { return("WALK"); } } } else { currentControlState = motionControlStates.onsurface; Falling = false; // Not walking if (heldDown) { return("CROUCH"); } else if (heldTurnLeft) { return("TURNLEFT"); } else if (heldTurnRight) { return("TURNRIGHT"); } else { return("STAND"); } } #endregion Ground Movement return(CurrentMovementAnimation); }
private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) { ScenePresence presence = m_scene.GetScenePresence(client.AgentId); if (presence != null) { // If this is an update for our own avatar give it the highest priority if (presence == entity) { return(0.0); } // Use group position for child prims Vector3 entityPos = entity.AbsolutePosition; if (entity is SceneObjectPart) { entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; } else { entityPos = entity.AbsolutePosition; } if (!presence.IsChildAgent) { if (entity is ScenePresence) { return(1.0); } // Root agent. Use distance from camera and a priority decrease for objects behind us Vector3 camPosition = presence.CameraPosition; Vector3 camAtAxis = presence.CameraAtAxis; // Distance double priority = Vector3.DistanceSquared(camPosition, entityPos); // Plane equation float d = -Vector3.Dot(camPosition, camAtAxis); float p = Vector3.Dot(camAtAxis, entityPos) + d; if (p < 0.0f) { priority *= 2.0; } if (entity is SceneObjectPart) { PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; if (physActor == null || !physActor.IsPhysical) { priority += 100; } if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) { priority = 1.0; } } return(priority); } else { // Child agent. Use the normal distance method Vector3 presencePos = presence.AbsolutePosition; return(Vector3.DistanceSquared(presencePos, entityPos)); } } return(double.NaN); }
private double GetPriorityByBestAvatarResponsiveness(IScenePresence presence, IEntity entity) { // If this is an update for our own avatar give it the highest priority if (presence.UUID == entity.UUID) { return(0.0); } if (entity == null) { return(double.NaN); } if (entity is IScenePresence) { return(1.0); } // Use group position for child prims Vector3 entityPos = entity.AbsolutePosition; if (!presence.IsChildAgent) { // Root agent. Use distance from camera and a priority decrease for objects behind us Vector3 camPosition = presence.CameraPosition; Vector3 camAtAxis = presence.CameraAtAxis; // Distance double priority = Vector3.DistanceSquared(camPosition, entityPos); // Plane equation float d = -Vector3.Dot(camPosition, camAtAxis); float p = Vector3.Dot(camAtAxis, entityPos) + d; if (p < 0.0f) { priority *= 2.0; } //Add distance again to really emphasize it priority += Vector3.DistanceSquared(presence.AbsolutePosition, entityPos); if ((Vector3.Distance(presence.AbsolutePosition, entityPos) / 2) > presence.DrawDistance) { //Outside of draw distance! priority *= 2; } SceneObjectPart rootPart = null; if (entity is SceneObjectPart) { if (((SceneObjectPart)entity).ParentGroup != null && ((SceneObjectPart)entity).ParentGroup.RootPart != null) { rootPart = ((SceneObjectPart)entity).ParentGroup.RootPart; } } if (entity is SceneObjectGroup) { if (((SceneObjectGroup)entity).RootPart != null) { rootPart = ((SceneObjectGroup)entity).RootPart; } } if (rootPart != null) { PhysicsActor physActor = rootPart.PhysActor; // Objects avatars are sitting on should be prioritized more if (presence.ParentID == rootPart.UUID) { //Objects that are physical get more priority. if (physActor != null && physActor.IsPhysical) { return(0.0); } else { return(1.2); } } if (physActor == null || physActor.IsPhysical) { priority /= 2; //Emphasize physical objs } //Factor in the size of objects as well, big ones are MUCH more important than small ones float size = rootPart.ParentGroup.GroupScale().Length(); //Cap size at 200 so that it doesn't completely overwhelm other objects if (size > 200) { size = 200; } //Do it dynamically as well so that larger prims get smaller quicker priority /= size > 40 ? (size / 35) : (size > 20 ? (size / 17) : 1); if (rootPart.IsAttachment) { //Attachments are always high! priority = 0.5; } } //Closest first! return(priority); } else { // Child agent. Use the normal distance method Vector3 presencePos = presence.AbsolutePosition; return(Vector3.DistanceSquared(presencePos, entityPos)); } }
public override void delink() { m_taintparent = null; }
public override void SetTerrain(bool[] heightMap) { if (m_terrainShape != null) { DeleteTerrain(); } m_terrainShape = AddPrim( "__TERRAIN__", new Vector3(Constants.RegionSize / 2, Constants.RegionSize / 2, Constants.RegionSize / 2), new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize), Quaternion.Identity, voxmesher.ToMesh(heightMap), PrimitiveBaseShape.Default, false); //float AabbCenterX = Constants.RegionSize/2f; //float AabbCenterY = Constants.RegionSize/2f; //float AabbCenterZ = 0f; /* * float temphfmin, temphfmax; * * temphfmin = hfmin; * temphfmax = hfmax; * * if (temphfmin < 0) * { * temphfmax = 0 - temphfmin; * temphfmin = 0 - temphfmin; * } * else if (temphfmin > 0) * { * temphfmax = temphfmax + (0 - temphfmin); * //temphfmin = temphfmin + (0 - temphfmin); * } * AabbCenterZ = temphfmax/2f; * * if (m_terrainPosition == null) * { * m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); * } * else * { * try * { * m_terrainPosition.setValue(AabbCenterX, AabbCenterY, AabbCenterZ); * } * catch (ObjectDisposedException) * { * m_terrainPosition = new btVector3(AabbCenterX, AabbCenterY, AabbCenterZ); * } * } */ if (m_terrainMotionState != null) { m_terrainMotionState.Dispose(); m_terrainMotionState = null; } m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition); m_terrainMotionState = new btDefaultMotionState(m_terrainTransform); }
public override void RemovePrim(PhysicsActor prim) { if (prim is BulletXPrim) { lock (BulletXLock) { try { ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody); } catch (Exception ex) { BulletXMessage(is_ex_message + ex.Message, true); ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation; AddForgottenRigidBody(((BulletXPrim) prim).RigidBody); } _prims.Remove(((BulletXPrim) prim).RigidBody); } GC.Collect(); } }
internal void remCollisionEventReporting(PhysicsActor bulletDotNETCharacter) { //TODO: FIXME: }
private void RemoveFromPhysicalScene(PhysicsActor physActor) { if (IsRootPart()) { m_parentGroup.Scene.PhysicsScene.RemovePrim(physActor); m_parentGroup.ForEachPart((SceneObjectPart part) => { part.PhysActor = null; } ); } }
public override void DeletePrim(PhysicsActor prim) { }
public override void RemoveAvatar(PhysicsActor actor) { }
public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) { int ret = -1; if (!Enabled) { return(ret); } // The part that is requesting the change. SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID); if (requestingPart != null) { // The change is always made to the root of a linkset. SceneObjectGroup containingGroup = requestingPart.ParentGroup; SceneObjectPart rootPart = containingGroup.RootPart; if (rootPart != null) { PhysicsActor rootPhysActor = rootPart.PhysActor; if (rootPhysActor != null) { if (rootPhysActor.IsPhysical) { // Change a physical linkset by making non-physical, waiting for one heartbeat so all // the prim and linkset state is updated, changing the type and making the // linkset physical again. containingGroup.ScriptSetPhysicsStatus(false); Thread.Sleep(150); // longer than one heartbeat tick // A kludge for the moment. // Since compound linksets move the children but don't generate position updates to the // simulator, it is possible for compound linkset children to have out-of-sync simulator // and physical positions. The following causes the simulator to push the real child positions // down into the physics engine to get everything synced. containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition); containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation); object[] parms2 = { rootPhysActor, null, linksetType }; ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2)); Thread.Sleep(150); // longer than one heartbeat tick containingGroup.ScriptSetPhysicsStatus(true); } else { // Non-physical linksets don't have a physical instantiation so there is no state to // worry about being updated. object[] parms2 = { rootPhysActor, null, linksetType }; ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2)); } } else { m_log.WarnFormat("{0} physSetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}", LogHeader, rootPart.Name, hostID); } } else { m_log.WarnFormat("{0} physSetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}", LogHeader, requestingPart.Name, hostID); } } else { m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID); } return(ret); }
public virtual void RemoveAllJointsConnectedToActorThreadLocked(PhysicsActor actor) { return; }
private bool GetRootPhysActor(UUID hostID, out SceneObjectGroup containingGroup, out SceneObjectPart rootPart, out PhysicsActor rootPhysActor) { bool ret = false; rootPhysActor = null; containingGroup = null; rootPart = null; SceneObjectPart requestingPart; requestingPart = BaseScene.GetSceneObjectPart(hostID); if (requestingPart != null) { // The type is is always on the root of a linkset. containingGroup = requestingPart.ParentGroup; if (containingGroup != null && !containingGroup.IsDeleted) { rootPart = containingGroup.RootPart; if (rootPart != null) { rootPhysActor = rootPart.PhysActor; if (rootPhysActor != null) { ret = true; } else { m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}", LogHeader, rootPart.Name, hostID); } } else { m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not exist. RequestingPartName={1}, hostID={2}", LogHeader, requestingPart.Name, hostID); } } else { m_log.WarnFormat("{0} GetRootAndChildPhysActors: Containing group missing or deleted. hostID={1}", LogHeader, hostID); } } else { m_log.WarnFormat("{0} GetRootAndChildPhysActors: cannot find script object in scene. hostID={1}", LogHeader, hostID); } return(ret); }
public override void RemovePrim(PhysicsActor prim) { if (!m_initialized) return; BSPhysObject bsprim = prim as BSPhysObject; if (bsprim != null) { DetailLog("{0},RemovePrim,call", bsprim.LocalID); // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); try { lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID); } catch (Exception e) { m_log.ErrorFormat("{0}: Attempt to remove prim that is not in physics scene: {1}", LogHeader, e); } bsprim.Destroy(); // bsprim.dispose(); } else { m_log.ErrorFormat("{0}: Attempt to remove prim that is not a BSPrim type.", LogHeader); } }
// Find the root and child PhysActors based on the linkNum. // Return 'true' if both are found and returned. private bool GetRootAndChildPhysActors(UUID hostID, int linkNum, out PhysicsActor rootPhysActor, out PhysicsActor childPhysActor) { bool ret = false; rootPhysActor = null; childPhysActor = null; SceneObjectGroup containingGroup; SceneObjectPart rootPart; if (GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor)) { SceneObjectPart linkPart = containingGroup.GetLinkNumPart(linkNum); if (linkPart != null) { childPhysActor = linkPart.PhysActor; if (childPhysActor != null) { ret = true; } else { m_log.WarnFormat("{0} GetRootAndChildPhysActors: Link part has no physical actor. rootName={1}, hostID={2}, linknum={3}", LogHeader, rootPart.Name, hostID, linkNum); } } else { m_log.WarnFormat("{0} GetRootAndChildPhysActors: Could not find linknum part. rootName={1}, hostID={2}, linknum={3}", LogHeader, rootPart.Name, hostID, linkNum); } } else { m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}", LogHeader, rootPart.Name, hostID); } return(ret); }
public override void AddPhysicsActorTaint(PhysicsActor prim) { //throw new NotSupportedException("AddPhysicsActorTaint must be called with a taint type"); }
/// <summary> /// This method determines the proper movement related animation /// </summary> private string DetermineMovementAnimation() { const float FALL_DELAY = 800f; const float PREJUMP_DELAY = 200f; const float JUMP_PERIOD = 800f; #region Inputs AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; PhysicsActor actor = m_scenePresence.PhysicsActor; // Create forward and left vectors from the current avatar rotation Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation); Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix); Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); // Check control flags bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS); bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG); bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK; if (heldForward || heldBack || heldLeft || heldRight || heldUp || heldDown) { heldTurnLeft = false; heldTurnRight = false; } // Direction in which the avatar is trying to move Vector3 move = Vector3.Zero; if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; } if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; } if (heldLeft) { move.X += left.X; move.Y += left.Y; } if (heldRight) { move.X -= left.X; move.Y -= left.Y; } if (heldUp) { move.Z += 1; } if (heldDown) { move.Z -= 1; } // Is the avatar trying to move? // bool moving = (move != Vector3.Zero); #endregion Inputs #region Flying if (actor != null && actor.Flying) { m_animTickFall = 0; m_animTickJump = 0; m_jumping = false; Falling = false; m_jumpVelocity = 0f; actor.Selected = false; m_fallHeight = actor.Position.Z; // save latest flying height if (move.X != 0f || move.Y != 0f) { return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY"); } else if (move.Z > 0f) { return("HOVER_UP"); } else if (move.Z < 0f) { if (actor != null && actor.IsColliding) { return("LAND"); } else { return("HOVER_DOWN"); } } else { return("HOVER"); } } #endregion Flying #region Falling/Floating/Landing if ((actor == null || !actor.IsColliding) && !m_jumping) { float fallElapsed = (float)(Environment.TickCount - m_animTickFall); float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; if (!m_jumping && (fallVelocity < -3.0f)) { Falling = true; } if (m_animTickFall == 0 || (fallVelocity >= 0.0f)) { // not falling yet, or going up // reset start of fall time m_animTickFall = Environment.TickCount; } else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.WasFlying)) { // Falling long enough to trigger the animation return("FALLDOWN"); } // Check if the user has stopped walking just now if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero)) { return("STAND"); } return(CurrentMovementAnimation); } #endregion Falling/Floating/Landing #region Jumping // section added for jumping... int jumptime; jumptime = Environment.TickCount - m_animTickJump; if ((move.Z > 0f) && (!m_jumping)) { // Start jumping, prejump m_animTickFall = 0; m_jumping = true; Falling = false; actor.Selected = true; // borrowed for jumping flag m_animTickJump = Environment.TickCount; m_jumpVelocity = 0.35f; return("PREJUMP"); } if (m_jumping) { if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding) { // end jumping m_jumping = false; Falling = false; actor.Selected = false; // borrowed for jumping flag m_jumpVelocity = 0f; m_animTickFall = Environment.TickCount; return("LAND"); } else if (jumptime > JUMP_PERIOD) { // jump down m_jumpVelocity = 0f; return("JUMP"); } else if (jumptime > PREJUMP_DELAY) { // jump up m_jumping = true; m_jumpVelocity = 10f; return("JUMP"); } } #endregion Jumping #region Ground Movement if (CurrentMovementAnimation == "FALLDOWN") { Falling = false; m_animTickFall = Environment.TickCount; // TODO: SOFT_LAND support float fallHeight = m_fallHeight - actor.Position.Z; if (fallHeight > 15.0f) { return("STANDUP"); } else if (fallHeight > 8.0f) { return("SOFT_LAND"); } else { return("LAND"); } } else if ((CurrentMovementAnimation == "LAND") || (CurrentMovementAnimation == "SOFT_LAND") || (CurrentMovementAnimation == "STANDUP")) { int landElapsed = Environment.TickCount - m_animTickFall; int limit = 1000; if (CurrentMovementAnimation == "LAND") { limit = 350; } // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client if ((m_animTickFall != 0) && (landElapsed <= limit)) { return(CurrentMovementAnimation); } else { m_fallHeight = actor.Position.Z; // save latest flying height return("STAND"); } } // next section moved outside paren. and realigned for jumping if (move.X != 0f || move.Y != 0f) { m_fallHeight = actor.Position.Z; // save latest flying height Falling = false; // Walking / crouchwalking / running if (move.Z < 0f) { return("CROUCHWALK"); } // We need to prevent these animations if the user tries to make their avatar walk or run whilst // specifying AGENT_CONTROL_STOP (pressing down space on viewers). else if (!m_scenePresence.AgentControlStopActive) { if (m_scenePresence.SetAlwaysRun) { return("RUN"); } else { return("WALK"); } } } else if (!m_jumping) { Falling = false; // Not walking if (move.Z < 0) { return("CROUCH"); } else if (heldTurnLeft) { return("TURNLEFT"); } else if (heldTurnRight) { return("TURNRIGHT"); } else { return("STAND"); } } #endregion Ground Movement Falling = false; return(CurrentMovementAnimation); }
public override void AddPhysicsActorTaint(PhysicsActor prim) { }
/// <summary> /// This method determines the proper movement related animation /// </summary> public string GetMovementAnimation() { const float FALL_DELAY = 0.33f; const float PREJUMP_DELAY = 0.25f; #region Inputs if (m_scenePresence.SitGround) { return("SIT_GROUND_CONSTRAINED"); } AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; PhysicsActor actor = m_scenePresence.PhysicsActor; // Create forward and left vectors from the current avatar rotation Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation); Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix); Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); // Check control flags bool heldForward = (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)); bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK; // Direction in which the avatar is trying to move Vector3 move = Vector3.Zero; if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; } if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; } if (heldLeft) { move.X += left.X; move.Y += left.Y; } if (heldRight) { move.X -= left.X; move.Y -= left.Y; } if (heldUp) { move.Z += 1; } if (heldDown) { move.Z -= 1; } // Is the avatar trying to move? // bool moving = (move != Vector3.Zero); bool jumping = m_animTickJump != 0; #endregion Inputs #region Flying if (actor != null && actor.Flying) { m_animTickFall = 0; m_animTickJump = 0; if (move.X != 0f || move.Y != 0f) { return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY"); } else if (move.Z > 0f) { return("HOVER_UP"); } else if (move.Z < 0f) { if (actor != null && actor.IsColliding) { return("LAND"); } else { return("HOVER_DOWN"); } } else { return("HOVER"); } } #endregion Flying #region Falling/Floating/Landing if (actor == null || !actor.IsColliding) { float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f)) { // Just started falling m_animTickFall = Environment.TickCount; } else if (!jumping && fallElapsed > FALL_DELAY) { // Falling long enough to trigger the animation return("FALLDOWN"); } else if (m_animTickJump == -1) { m_animTickJump = 0; return("STAND"); } return(m_movementAnimation); } #endregion Falling/Floating/Landing #region Ground Movement if (m_movementAnimation == "FALLDOWN") { m_animTickFall = Environment.TickCount; // TODO: SOFT_LAND support return("LAND"); } else if (m_movementAnimation == "LAND") { float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY)) { return("LAND"); } } m_animTickFall = 0; if (move.Z > 0f) { // Jumping if (!jumping) { // Begin prejump m_animTickJump = Environment.TickCount; return("PREJUMP"); } else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f) { // Start actual jump if (m_animTickJump == -1) { // Already jumping! End the current jump m_animTickJump = 0; return("JUMP"); } m_animTickJump = -1; return("JUMP"); } else { return("JUMP"); } } else { // Not jumping m_animTickJump = 0; if (move.X != 0f || move.Y != 0f) { // Walking / crouchwalking / running if (move.Z < 0f) { return("CROUCHWALK"); } else if (m_scenePresence.SetAlwaysRun) { return("RUN"); } else { return("WALK"); } } else { // Not walking if (move.Z < 0f) { return("CROUCH"); } else { return("STAND"); } } } #endregion Ground Movement //return m_movementAnimation; }
public override void link(PhysicsActor obj) { m_taintparent = obj; }
public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse) { if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero) { PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity); return; } IntPtr geom = ((OdePrim)actor).prim_geom; Vector3 geopos = d.GeomGetPositionOMV(geom); Quaternion geomOri = d.GeomGetQuaternionOMV(geom); // Vector3 geopos = actor.Position; // Quaternion geomOri = actor.Orientation; Quaternion geomInvOri = Quaternion.Conjugate(geomOri); Quaternion ori = Quaternion.Identity; Vector3 rayDir = geopos + offset - avCameraPosition; float raylen = rayDir.Length(); if (raylen < 0.001f) { PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity); return; } float t = 1 / raylen; rayDir.X *= t; rayDir.Y *= t; rayDir.Z *= t; raylen += 30f; // focal point may be far List <ContactResult> rayResults; rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags); if (rayResults.Count == 0) { /* if this fundamental ray failed, then just fail so user can try another spot and not be sitted far on a big prim * d.AABB aabb; * d.GeomGetAABB(geom, out aabb); * offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z); * ori = geomInvOri; * offset *= geomInvOri; * PhysicsSitResponse(1, actor.LocalID, offset, ori); */ PhysicsSitResponse(0, actor.LocalID, offset, ori); return; } int status = 1; offset = rayResults[0].Pos - geopos; d.GeomClassID geoclass = d.GeomGetClass(geom); if (geoclass == d.GeomClassID.SphereClass) { float r = d.GeomSphereGetRadius(geom); offset.Normalize(); offset *= r; RotAroundZ(offset.X, offset.Y, ref ori); if (r < 0.4f) { offset = new Vector3(0, 0, r); } else { if (offset.Z < 0.4f) { t = offset.Z; float rsq = r * r; t = 1.0f / (rsq - t * t); offset.X *= t; offset.Y *= t; offset.Z = 0.4f; t = rsq - 0.16f; offset.X *= t; offset.Y *= t; } else if (r > 0.8f && offset.Z > 0.8f * r) { status = 3; avOffset.X = -avOffset.X; avOffset.Z *= 1.6f; } } offset += avOffset * ori; ori = geomInvOri * ori; offset *= geomInvOri; PhysicsSitResponse(status, actor.LocalID, offset, ori); return; } Vector3 norm = rayResults[0].Normal; if (norm.Z < -0.4f) { PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity); return; } float SitNormX = -rayDir.X; float SitNormY = -rayDir.Y; Vector3 pivot = geopos + offset; float edgeNormalX = norm.X; float edgeNormalY = norm.Y; float edgeDirX = -rayDir.X; float edgeDirY = -rayDir.Y; Vector3 edgePos = rayResults[0].Pos; float edgeDist = float.MaxValue; bool foundEdge = false; if (norm.Z < 0.5f) { float rayDist = 4.0f; for (int i = 0; i < 6; i++) { pivot.X -= 0.01f * norm.X; pivot.Y -= 0.01f * norm.Y; pivot.Z -= 0.01f * norm.Z; rayDir.X = -norm.X * norm.Z; rayDir.Y = -norm.Y * norm.Z; rayDir.Z = 1.0f - norm.Z * norm.Z; rayDir.Normalize(); rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims); if (rayResults.Count == 0) { break; } if (Math.Abs(rayResults[0].Normal.Z) < 0.7f) { rayDist -= rayResults[0].Depth; if (rayDist < 0f) { break; } pivot = rayResults[0].Pos; norm = rayResults[0].Normal; edgeNormalX = norm.X; edgeNormalY = norm.Y; edgeDirX = -rayDir.X; edgeDirY = -rayDir.Y; } else { foundEdge = true; edgePos = rayResults[0].Pos; break; } } if (!foundEdge) { PhysicsSitResponse(0, actor.LocalID, offset, ori); return; } avOffset.X *= 0.5f; } else if (norm.Z > 0.866f) { float toCamBaseX = avCameraPosition.X - pivot.X; float toCamBaseY = avCameraPosition.Y - pivot.Y; float toCamX = toCamBaseX; float toCamY = toCamBaseY; for (int j = 0; j < 4; j++) { float rayDist = 1.0f; float curEdgeDist = 0.0f; for (int i = 0; i < 3; i++) { pivot.Z -= 0.01f; rayDir.X = toCamX; rayDir.Y = toCamY; rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z; rayDir.Normalize(); rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims); if (rayResults.Count == 0) { break; } curEdgeDist += rayResults[0].Depth; if (rayResults[0].Normal.Z > 0.5f) { rayDist -= rayResults[0].Depth; if (rayDist < 0f) { break; } pivot = rayResults[0].Pos; norm = rayResults[0].Normal; } else { foundEdge = true; if (curEdgeDist < edgeDist) { edgeDist = curEdgeDist; edgeNormalX = rayResults[0].Normal.X; edgeNormalY = rayResults[0].Normal.Y; edgeDirX = rayDir.X; edgeDirY = rayDir.Y; edgePos = rayResults[0].Pos; } break; } } if (foundEdge && edgeDist < 0.2f) { break; } pivot = geopos + offset; switch (j) { case 0: toCamX = -toCamBaseY; toCamY = toCamBaseX; break; case 1: toCamX = toCamBaseY; toCamY = -toCamBaseX; break; case 2: toCamX = -toCamBaseX; toCamY = -toCamBaseY; break; default: break; } } if (!foundEdge) { avOffset.X = -avOffset.X; avOffset.Z *= 1.6f; RotAroundZ(SitNormX, SitNormY, ref ori); offset += avOffset * ori; ori = geomInvOri * ori; offset *= geomInvOri; PhysicsSitResponse(3, actor.LocalID, offset, ori); return; } avOffset.X *= 0.5f; } SitNormX = edgeNormalX; SitNormY = edgeNormalY; if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0) { SitNormX = -SitNormX; SitNormY = -SitNormY; } RotAroundZ(SitNormX, SitNormY, ref ori); offset = edgePos + avOffset * ori; offset -= geopos; ori = geomInvOri * ori; offset *= geomInvOri; PhysicsSitResponse(1, actor.LocalID, offset, ori); return; }
private void changelink(float timestep) { // If the newly set parent is not null // create link if (_parent == null && m_taintparent != null) { if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim) { OdePrim obj = (OdePrim)m_taintparent; //obj.disableBody(); //Console.WriteLine("changelink calls ParentPrim"); obj.AddChildPrim(this); /* if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) { _linkJointGroup = d.JointGroupCreate(0); m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); d.JointAttach(m_linkJoint, obj.Body, Body); d.JointSetFixed(m_linkJoint); } */ } } // If the newly set parent is null // destroy link else if (_parent != null && m_taintparent == null) { //Console.WriteLine(" changelink B"); if (_parent is OdePrim) { OdePrim obj = (OdePrim)_parent; obj.ChildDelink(this); childPrim = false; //_parent = null; } /* if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0) d.JointGroupDestroy(_linkJointGroup); _linkJointGroup = (IntPtr)0; m_linkJoint = (IntPtr)0; */ } _parent = m_taintparent; m_taintPhysics = IsPhysical; }
// This is the standard Near. g1 is the ray private void near(IntPtr space, IntPtr g1, IntPtr g2) { if (g2 == IntPtr.Zero || g1 == g2) { return; } if (m_contactResults.Count >= CurrentMaxCount) { return; } if (SafeNativeMethods.GeomIsSpace(g2)) { try { SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (Exception e) { m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message); } return; } int count = 0; try { count = SafeNativeMethods.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } catch (Exception e) { m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message); return; } if (count == 0) { return; } /* * uint cat1 = d.GeomGetCategoryBits(g1); * uint cat2 = d.GeomGetCategoryBits(g2); * uint col1 = d.GeomGetCollideBits(g1); * uint col2 = d.GeomGetCollideBits(g2); */ uint ID = 0; PhysicsActor p2 = null; m_scene.actor_name_map.TryGetValue(g2, out p2); if (p2 == null) { return; } switch (p2.PhysicsActorType) { case (int)ActorTypes.Prim: RayFilterFlags thisFlags; if (p2.IsPhysical) { thisFlags = RayFilterFlags.physical; } else { thisFlags = RayFilterFlags.nonphysical; } if (p2.Phantom) { thisFlags |= RayFilterFlags.phantom; } if (p2.IsVolumeDtc) { thisFlags |= RayFilterFlags.volumedtc; } if ((thisFlags & CurrentRayFilter) == 0) { return; } ID = ((OdePrim)p2).LocalID; break; case (int)ActorTypes.Agent: if ((CurrentRayFilter & RayFilterFlags.agent) == 0) { return; } else { ID = ((OdeCharacter)p2).LocalID; } break; case (int)ActorTypes.Ground: if ((CurrentRayFilter & RayFilterFlags.land) == 0) { return; } break; case (int)ActorTypes.Water: if ((CurrentRayFilter & RayFilterFlags.water) == 0) { return; } break; default: break; } SafeNativeMethods.ContactGeom curcontact = new SafeNativeMethods.ContactGeom(); // closestHit for now only works for meshs, so must do it for others if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0) { // Loop all contacts, build results. for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curcontact)) { break; } ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = ID; collisionresult.Pos.X = curcontact.pos.X; collisionresult.Pos.Y = curcontact.pos.Y; collisionresult.Pos.Z = curcontact.pos.Z; collisionresult.Depth = curcontact.depth; collisionresult.Normal.X = curcontact.normal.X; collisionresult.Normal.Y = curcontact.normal.Y; collisionresult.Normal.Z = curcontact.normal.Z; lock (m_contactResults) { m_contactResults.Add(collisionresult); if (m_contactResults.Count >= CurrentMaxCount) { return; } } } } else { // keep only closest contact ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = ID; collisionresult.Depth = float.MaxValue; for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curcontact)) { break; } if (curcontact.depth < collisionresult.Depth) { collisionresult.Pos.X = curcontact.pos.X; collisionresult.Pos.Y = curcontact.pos.Y; collisionresult.Pos.Z = curcontact.pos.Z; collisionresult.Depth = curcontact.depth; collisionresult.Normal.X = curcontact.normal.X; collisionresult.Normal.Y = curcontact.normal.Y; collisionresult.Normal.Z = curcontact.normal.Z; } } if (collisionresult.Depth != float.MaxValue) { lock (m_contactResults) m_contactResults.Add(collisionresult); } } }
public override void RemoveAvatar(PhysicsActor actor) { if (actor is BulletXCharacter) { lock (BulletXLock) { try { ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody); } catch (Exception ex) { BulletXMessage(is_ex_message + ex.Message, true); ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation; AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody); } _characters.Remove(((BulletXCharacter) actor).RigidBody); } GC.Collect(); } }
/// <summary> /// This method determines the proper movement related animation /// </summary> public string GetMovementAnimation() { const float STANDUP_TIME = 2f; const float BRUSH_TIME = 3.5f; const float FALL_AFTER_MOVE_TIME = 0.75f; const float SOFTLAND_FORCE = 80; #region Inputs if (m_scenePresence.SitGround) { return("SIT_GROUND_CONSTRAINED"); } AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; PhysicsActor actor = m_scenePresence.PhysicsActor; // Create forward and left vectors from the current avatar rotation Vector3 fwd = Vector3.UnitX * m_scenePresence.Rotation; Vector3 left = Vector3.UnitY * m_scenePresence.Rotation; // Check control flags bool heldForward = (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)); bool yawPos = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) == AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS; bool yawNeg = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG; bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY; //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK; // Direction in which the avatar is trying to move Vector3 move = Vector3.Zero; if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; } if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; } if (heldLeft) { move.X += left.X; move.Y += left.Y; } if (heldRight) { move.X -= left.X; move.Y -= left.Y; } if (heldUp) { move.Z += 1; } if (heldDown) { move.Z -= 1; } float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; if (heldTurnLeft && yawPos && !heldForward && !heldBack && actor != null && !actor.IsJumping && !actor.Flying && move.Z == 0 && fallVelocity == 0.0f && !heldUp && !heldDown && move.CompareTo(Vector3.Zero) == 0) { return("TURNLEFT"); } if (heldTurnRight && yawNeg && !heldForward && !heldBack && actor != null && !actor.IsJumping && !actor.Flying && move.Z == 0 && fallVelocity == 0.0f && !heldUp && !heldDown && move.CompareTo(Vector3.Zero) == 0) { return("TURNRIGHT"); } // Is the avatar trying to move? // bool moving = (move != Vector3.Zero); #endregion Inputs #region Standup float standupElapsed = (Util.EnvironmentTickCount() - m_animTickStandup) / 1000f; if (m_scenePresence.PhysicsActor != null && standupElapsed < STANDUP_TIME && m_useSplatAnimation) { // Falling long enough to trigger the animation m_scenePresence.FallenStandUp = true; m_scenePresence.PhysicsActor.Velocity = Vector3.Zero; return("STANDUP"); } // need the brush off? if (standupElapsed < BRUSH_TIME && m_useSplatAnimation) { m_scenePresence.FallenStandUp = true; return("BRUSH"); } if (m_animTickStandup != 0 || m_scenePresence.FallenStandUp) { m_scenePresence.FallenStandUp = false; m_animTickStandup = 0; } #endregion Standup #region Flying if (actor != null && (m_scenePresence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) == (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY || m_scenePresence.ForceFly) { m_animTickWalk = 0; m_animTickFall = 0; if (move.X != 0f || move.Y != 0f) { // level? if (move.Z == 0) { if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics && actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight) { return("SWIM_FORWARD"); } // must be flying then if (m_timesBeforeSlowFlyIsOff < SLOWFLY_DELAY) { m_timesBeforeSlowFlyIsOff++; return("FLYSLOW"); } return("FLY"); } // going up then... if (move.Z > 0) { if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics && actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight) { return("SWIM_UP"); } // easy does it return("FLYSLOW"); } if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics && actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight) { return("SWIM_DOWN"); } // in the wild blue yonder return("FLY"); } // moving left/right but going up as well? if (move.Z > 0f) { //This is for the slow fly timer m_timesBeforeSlowFlyIsOff = 0; if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics && actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight) { return("SWIM_UP"); } // going up... return("HOVER_UP"); } // mabye moving down then? if (move.Z < 0f) { wasLastFlying = true; //This is for the slow fly timer m_timesBeforeSlowFlyIsOff = 0; if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics && actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight) { return("SWIM_DOWN"); } else { ITerrainChannel channel = m_scenePresence.Scene.RequestModuleInterface <ITerrainChannel> (); if (channel != null) { float groundHeight = channel.GetNormalizedGroundHeight((int)m_scenePresence.AbsolutePosition.X, (int)m_scenePresence.AbsolutePosition.Y); if (actor != null && (m_scenePresence.AbsolutePosition.Z - groundHeight) < 2) { return("LAND"); } return("HOVER_DOWN"); } // no ground here... return("HOVER_DOWN"); } } //This is for the slow fly timer m_timesBeforeSlowFlyIsOff = 0; if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics && actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight) { return("SWIM_HOVER"); } return("HOVER"); } m_timesBeforeSlowFlyIsOff = 0; #endregion Flying #region Jumping if (actor != null && actor.IsJumping) { return("JUMP"); } if (actor != null && actor.IsPreJumping) { return("PREJUMP"); } #endregion #region Falling/Floating/Landing float walkElapsed = (Util.EnvironmentTickCount() - m_animTickWalk) / 1000f; if (actor != null && actor.IsPhysical && !actor.IsJumping && (!actor.IsColliding) && !actor.Flying && actor.TargetVelocity != Vector3.Zero /* && actor.Velocity.Z < -2*/ && (walkElapsed > FALL_AFTER_MOVE_TIME || m_animTickWalk == 0))//For if they user is walking off something, or they are falling { //Always return falldown immediately as there shouldn't be a waiting period if (m_animTickFall == 0) { m_animTickFall = Util.EnvironmentTickCount(); } return("FALLDOWN"); } #endregion Falling/Floating/Landing #region Ground Movement if (m_movementAnimation == "FALLDOWN") { float fallElapsed = (Util.EnvironmentTickCount() - m_animTickFall) / 1000f; // soft landing? if (fallElapsed < 0.75) { m_animTickFall = Util.EnvironmentTickCount(); return("SOFT_LAND"); } // a bit harder then? if (actor != null && (fallElapsed < 1.1 || (Math.Abs(actor.Velocity.X) > 1 && Math.Abs(actor.Velocity.Y) > 1 && actor.Velocity.Z < 3) ) ) { m_animTickFall = Util.EnvironmentTickCount(); return("LAND"); } // maybe a hard one... if (m_useSplatAnimation) { m_animTickStandup = Util.EnvironmentTickCount(); return("STANDUP"); } // just a simple landing return("LAND"); } // landing then if (m_movementAnimation == "LAND") { if (actor != null && actor.Velocity.Z < 0) { if (actor.Velocity.Z < SOFTLAND_FORCE) { return("LAND"); } return("SOFT_LAND"); } //return "LAND"; } m_animTickFall = 0; if (move.Z <= 0f) { if (actor != null && (move.X != 0f || move.Y != 0f || actor.Velocity.X != 0 && actor.Velocity.Y != 0)) { wasLastFlying = false; if (actor.IsColliding) { m_animTickWalk = Util.EnvironmentTickCount(); } // Walking / crouchwalking / running if (move.Z < 0f) { return("CROUCHWALK"); } // always run? if (m_scenePresence.SetAlwaysRun) { return("RUN"); } // must be walking then return("WALK"); } // Not walking if (move.Z < 0f && !wasLastFlying) { return("CROUCH"); } return("STAND"); } #endregion Ground Movement // none of the above so just continue the last animation return(m_movementAnimation); }
public override void LinkToNewParent(PhysicsActor obj, Vector3 localPos, Quaternion localRot) { }
public void StopMoveToTarget() { PhysicsActor?.DeactivateTargetList(); }
public void SetParentAndUpdatePhysics(SceneObjectGroup parent) { this.SetParent(parent, false); PhysicsActor physActor = PhysActor; if (physActor != null) { //does the parent have a physactor? PhysicsActor parentPhysactor = parent.RootPart.PhysActor; if (parentPhysactor != null) { physActor.LinkToNewParent(parent.RootPart.PhysActor, this.OffsetPosition, this.RotationOffset); } else { //we're linking a non-phantom prim to a phantom parent, phantomize this prim as well //NOTE: Don't use UpdatePrimFlags here, it only works for roots, and this is not a root //any longer this.AddFlag(PrimFlags.Phantom); m_parentGroup.Scene.PhysicsScene.RemovePrim(physActor); PhysActor = null; } } }
// This is the standard Near. Uses space AABBs to speed up detection. private void near(IntPtr space, IntPtr g1, IntPtr g2) { //Don't test against heightfield Geom, or you'll be sorry! /* * terminate called after throwing an instance of 'std::bad_alloc' * what(): std::bad_alloc * Stacktrace: * * at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004> * at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff> * at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280> * at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff * fffff> * at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004> * at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff> * at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) < * 0x00114> * at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb> * at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6> * at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042> * at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e> * at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019> * at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff> * * Native stacktrace: * * mono [0x80d2a42] * [0xb7f5840c] * /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018] * /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988] * /usr/lib/libstdc++.so.6 [0xb45fa865] * /usr/lib/libstdc++.so.6 [0xb45fa8a2] * /usr/lib/libstdc++.so.6 [0xb45fa9da] * /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033] * /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d] * libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4] * libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b] * libode.so(dCollide+0x102) [0xb46571b2] * [0x95cfdec9] * [0x8ea07fe1] * [0xab260146] * libode.so [0xb465a5c4] * libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5] * libode.so(dSpaceCollide2+0x177) [0xb465ac67] * [0x95cf978e] * [0x8ea07945] * [0x95cf2bbc] * [0xab2787e7] * [0xab419fb3] * [0xab416657] * [0xab415bda] * [0xb609b08e] * mono(mono_runtime_delegate_invoke+0x34) [0x8192534] * mono [0x81a2f0f] * mono [0x81d28b6] * mono [0x81ea2c6] * /lib/i686/cmov/libpthread.so.0 [0xb7e744c0] * /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de] */ // Exclude heightfield geom if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) { return; } // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } //Colliding a space or a geom with a space or a geom. so drill down //Collide all geoms in each space.. //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } int count = 0; try { if (g1 == g2) { return; // Can't collide with yourself } lock (contacts) { count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); } } catch (SEHException) { m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); } catch (Exception e) { m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); return; } PhysicsActor p1 = null; PhysicsActor p2 = null; if (g1 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p1); } if (g2 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p2); } // Loop over contacts, build results. for (int i = 0; i < count; i++) { if (p1 != null) { if (p1 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = p1.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } } if (p2 != null) { if (p2 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = p2.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } } } }
// link me to the specified parent public override void link(PhysicsActor obj) { BSPrim parent = (BSPrim)obj; // m_log.DebugFormat("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); // TODO: decide if this parent checking needs to happen at taint time if (_parentPrim == null) { if (parent != null) { // I don't have a parent so I am joining a linkset parent.AddChildToLinkset(this); } } else { // I already have a parent, is parenting changing? if (parent != _parentPrim) { if (parent == null) { // we are being removed from a linkset _parentPrim.RemoveChildFromLinkset(this); } else { // asking to reparent a prim should not happen m_log.ErrorFormat("{0}: Reparenting a prim. ", LogHeader); } } } return; }
public override void AddPhysicsActorTaint(PhysicsActor prim, TaintType taint) { }
public void UpdatePrimFlags(bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVD) { bool wasUsingPhysics = ((ObjectFlags & (uint) PrimFlags.Physics) != 0); bool wasTemporary = ((ObjectFlags & (uint)PrimFlags.TemporaryOnRez) != 0); bool wasPhantom = ((ObjectFlags & (uint)PrimFlags.Phantom) != 0); bool wasVD = VolumeDetectActive; if ((UsePhysics == wasUsingPhysics) && (wasTemporary == IsTemporary) && (wasPhantom == IsPhantom) && (IsVD==wasVD)) { return; } // Special cases for VD. VD can only be called from a script // and can't be combined with changes to other states. So we can rely // that... // ... if VD is changed, all others are not. // ... if one of the others is changed, VD is not. if (IsVD) // VD is active, special logic applies { // State machine logic for VolumeDetect // More logic below bool phanReset = (IsPhantom != wasPhantom) && !IsPhantom; if (phanReset) // Phantom changes from on to off switch VD off too { IsVD = false; // Switch it of for the course of this routine VolumeDetectActive = false; // and also permanently if (PhysActor != null) PhysActor.SetVolumeDetect(0); // Let physics know about it too } else { IsPhantom = false; // If volumedetect is active we don't want phantom to be applied. // If this is a new call to VD out of the state "phantom" // this will also cause the prim to be visible to physics } } if (UsePhysics && IsJoint()) { IsPhantom = true; } if (UsePhysics) { AddFlag(PrimFlags.Physics); if (!wasUsingPhysics) { DoPhysicsPropertyUpdate(UsePhysics, false); if (m_parentGroup != null) { if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { m_parentGroup.CheckSculptAndLoad(); } } } } } else { RemFlag(PrimFlags.Physics); if (wasUsingPhysics) { DoPhysicsPropertyUpdate(UsePhysics, false); } } if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints { AddFlag(PrimFlags.Phantom); if (PhysActor != null) { m_parentGroup.Scene.PhysicsScene.RemovePrim(PhysActor); /// that's not wholesome. Had to make Scene public PhysActor = null; } } else // Not phantom { RemFlag(PrimFlags.Phantom); PhysicsActor pa = PhysActor; if (pa == null) { // It's not phantom anymore. So make sure the physics engine get's knowledge of it PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( Name, Shape, AbsolutePosition, Scale, RotationOffset, UsePhysics); pa = PhysActor; if (pa != null) { pa.LocalID = LocalId; DoPhysicsPropertyUpdate(UsePhysics, true); if (m_parentGroup != null) { if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { m_parentGroup.CheckSculptAndLoad(); } } } if ( ((AggregateScriptEvents & scriptEvents.collision) != 0) || ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || (CollisionSound != UUID.Zero) ) { PhysActor.OnCollisionUpdate += PhysicsCollision; PhysActor.SubscribeEvents(1000); } } } else // it already has a physical representation { pa.IsPhysical = UsePhysics; DoPhysicsPropertyUpdate(UsePhysics, false); // Update physical status. If it's phantom this will remove the prim if (m_parentGroup != null) { if (!m_parentGroup.IsDeleted) { if (LocalId == m_parentGroup.RootPart.LocalId) { m_parentGroup.CheckSculptAndLoad(); } } } } } if (IsVD) { // If the above logic worked (this is urgent candidate to unit tests!) // we now have a physicsactor. // Defensive programming calls for a check here. // Better would be throwing an exception that could be catched by a unit test as the internal // logic should make sure, this Physactor is always here. if (this.PhysActor != null) { PhysActor.SetVolumeDetect(1); AddFlag(PrimFlags.Phantom); // We set this flag also if VD is active this.VolumeDetectActive = true; } } else { // Remove VolumeDetect in any case. Note, it's safe to call SetVolumeDetect as often as you like // (mumbles, well, at least if you have infinte CPU powers :-)) PhysicsActor pa = this.PhysActor; if (pa != null) { PhysActor.SetVolumeDetect(0); } this.VolumeDetectActive = false; } if (IsTemporary) { AddFlag(PrimFlags.TemporaryOnRez); } else { RemFlag(PrimFlags.TemporaryOnRez); } // m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString()); ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); }
public override void LinkToNewParent(PhysicsActor obj, Vector3 localPos, Quaternion localRot) { }
public override void RemovePrim(PhysicsActor prim) { }
public void refresh(Vector3 influence, bool jump, bool sprint, bool crouch) { //Debug.Log("Hello?"); capsuleOffsets[0] = Vector3.up * (settings.stepUpMax + settings.collisionRadius); capsuleOffsets[1] = capsuleOffsets[0] + Vector3.up * settings.collisionHeight; currentVelocity = currentPhysics.getVelocity(); Vector3 workingInfluence = influence; switch (currentPhysicsMode) { case PhysicsModes.STANDING: case PhysicsModes.WALKING: case PhysicsModes.RUNNING: { Debug.Log("GROUNDED!!"); if (!currentPhysics.inValidState()) { //if on a slidable terrain. currentPhysics = movementSelection[(int)key.AIR_TRAVERSAL]; currentPhysicsMode = PhysicsModes.AIRBORNE; currentPhysics.reset(); currentPhysics.setVelocity(currentVelocity); } if (jump) { //if infront of climable that fits a vaulatable, and enough speed, vault it //else if infront of climbable and moving towards it, step up it. currentPhysics = movementSelection[(int)key.AIR_TRAVERSAL]; //AIR TRAVERSAL currentPhysicsMode = PhysicsModes.AIRBORNE; currentPhysics.reset(); currentPhysics.setVelocity(currentVelocity); workingInfluence.y = 1; } } break; case PhysicsModes.CROUCHING: case PhysicsModes.SLIDING: { } break; case PhysicsModes.CLIMBING: { } break; case PhysicsModes.AIRBORNE: default: { Debug.Log("AIRBORNE!!"); if (!currentPhysics.inValidState()) { Debug.Log("in-valid"); currentPhysicsMode = PhysicsModes.STANDING; currentPhysics = movementSelection[(int)key.GROUND_TRAVERSAL]; currentPhysics.setVelocity(currentVelocity); } } break; } currentPhysics.refresh(workingInfluence); }
/// <summary> /// Remove a prim. /// </summary> /// <param name="prim"></param> public abstract void RemovePrim(PhysicsActor prim);
public override void RemovePrim(PhysicsActor prim) { }
public abstract void AddPhysicsActorTaint(PhysicsActor prim);
public override void RemoveAvatar(PhysicsActor actor) { this.QueueCommand(new Commands.RemoveCharacterCmd((PhysxCharacter)actor)); }
public override void RemoveAvatar(PhysicsActor actor) { // m_log.DebugFormat("{0}: RemoveAvatar", LogHeader); if (!m_initialized) return; BSCharacter bsactor = actor as BSCharacter; if (bsactor != null) { try { lock (PhysObjects) PhysObjects.Remove(bsactor.LocalID); // Remove kludge someday lock (m_avatars) m_avatars.Remove(bsactor); } catch (Exception e) { m_log.WarnFormat("{0}: Attempt to remove avatar that is not in physics scene: {1}", LogHeader, e); } bsactor.Destroy(); // bsactor.dispose(); } else { m_log.ErrorFormat("{0}: Requested to remove avatar that is not a BSCharacter. ID={1}, type={2}", LogHeader, actor.LocalID, actor.GetType().Name); } }
public override void RemovePrim(PhysicsActor prim) { this.QueueCommand(new Commands.RemoveObjectCmd((PhysxPrim)prim)); }
// This is a call from the simulator saying that some physical property has been updated. // The BulletSim driver senses the changing of relevant properties so this taint // information call is not needed. public override void AddPhysicsActorTaint(PhysicsActor prim) { }
public override void AddPhysicsActorTaint(PhysicsActor prim) { //throw new NotSupportedException("AddPhysicsActorTaint must be called with a taint type"); }
public override void RemovePrim(PhysicsActor prim) { this.QueueCommand(new Commands.RemoveObjectCmd((PhysxPrim)prim)); }
public override void link(PhysicsActor obj) { return; }
public override void AddPhysicsActorTaint(PhysicsActor prim, TaintType taint) { TaintHandler handler; if (_taintHandlers.TryGetValue(taint, out handler)) { handler((PhysxPrim)prim, taint); } }
// This is the standard Near. Uses space AABBs to speed up detection. private void near(IntPtr space, IntPtr g1, IntPtr g2) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } // if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) // return; // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } //Colliding a space or a geom with a space or a geom. so drill down //Collide all geoms in each space.. //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) { return; } int count = 0; try { if (g1 == g2) { return; // Can't collide with yourself } lock (contacts) { count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.unmanagedSizeOf); } } catch (SEHException) { m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); } catch (Exception e) { m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); return; } PhysicsActor p1 = null; PhysicsActor p2 = null; if (g1 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p1); } if (g2 != IntPtr.Zero) { m_scene.actor_name_map.TryGetValue(g1, out p2); } // Loop over contacts, build results. for (int i = 0; i < count; i++) { if (p1 != null) { if (p1 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = p1.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } } if (p2 != null) { if (p2 is OdePrim) { ContactResult collisionresult = new ContactResult(); collisionresult.ConsumerID = p2.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } } } }