// Set this sets and computes the displacement from the passed prim to the center-of-mass. // A user set value for center-of-mass overrides whatever might be passed in here. // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) { Vector3 comDisp; if (UserSetCenterOfMassDisplacement.HasValue) { comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; } else { comDisp = centerOfMassDisplacement; } DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}", LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp); if (comDisp == Vector3.Zero) { // If there is no diplacement. Things get reset. PositionDisplacement = OMV.Vector3.Zero; OrientationDisplacement = OMV.Quaternion.Identity; } else { // Remember the displacement from root as well as the origional rotation of the // new center-of-mass. PositionDisplacement = comDisp; OrientationDisplacement = OMV.Quaternion.Identity; } }
public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r) { Index = indx; OffsetFromRoot = p; OffsetFromCenterOfMass = p; OffsetRot = r; }
public override void Clear() { Index = 0; OffsetFromRoot = OMV.Vector3.Zero; OffsetFromCenterOfMass = OMV.Vector3.Zero; OffsetRot = OMV.Quaternion.Identity; }
public EntityCamera(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { m_yawFixed = true; m_globalPosition = new OMV.Vector3d(40f, 40f, 30f); m_heading = new OMV.Quaternion(0f, 1f, 0f); }
// Set this sets and computes the displacement from the passed prim to the center-of-mass. // A user set value for center-of-mass overrides whatever might be passed in here. // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). public virtual void SetEffectiveCenterOfMassW(Vector3 centerOfMassDisplacement) { Vector3 comDisp; if (UserSetCenterOfMass.HasValue) { comDisp = (OMV.Vector3)UserSetCenterOfMass; } else { comDisp = centerOfMassDisplacement; } if (comDisp == Vector3.Zero) { // If there is no diplacement. Things get reset. PositionDisplacement = OMV.Vector3.Zero; OrientationDisplacement = OMV.Quaternion.Identity; } else { // Remember the displacement from root as well as the origional rotation of the // new center-of-mass. PositionDisplacement = comDisp; OrientationDisplacement = OMV.Quaternion.Identity; } }
// Set all the parameters for this constraint to a fixed, non-movable constraint. public override void ResetLink() { // constraintType = ConstraintType.D6_CONSTRAINT_TYPE; constraintType = ConstraintType.BS_FIXED_CONSTRAINT_TYPE; linearLimitLow = OMV.Vector3.Zero; linearLimitHigh = OMV.Vector3.Zero; angularLimitLow = OMV.Vector3.Zero; angularLimitHigh = OMV.Vector3.Zero; useFrameOffset = BSParam.LinkConstraintUseFrameOffset; enableTransMotor = BSParam.LinkConstraintEnableTransMotor; transMotorMaxVel = BSParam.LinkConstraintTransMotorMaxVel; transMotorMaxForce = BSParam.LinkConstraintTransMotorMaxForce; cfm = BSParam.LinkConstraintCFM; erp = BSParam.LinkConstraintERP; solverIterations = BSParam.LinkConstraintSolverIterations; frameInAloc = OMV.Vector3.Zero; frameInArot = OMV.Quaternion.Identity; frameInBloc = OMV.Vector3.Zero; frameInBrot = OMV.Quaternion.Identity; useLinearReferenceFrameA = true; springAxisEnable = new bool[6]; springDamping = new float[6]; springStiffness = new float[6]; for (int ii = 0; ii < springAxisEnable.Length; ii++) { springAxisEnable[ii] = false; springDamping[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED; springStiffness[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED; } springLinearEquilibriumPoint = OMV.Vector3.Zero; springAngularEquilibriumPoint = OMV.Vector3.Zero; member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.ResetLink", member.LocalID); }
public void Populate(Scene scene) { SceneObjectPart part = scene.GetSceneObjectPart(Key); if (part == null) // Avatar, maybe? { ScenePresence presence = scene.GetScenePresence(Key); if (presence == null) { return; } Name = presence.Firstname + " " + presence.Lastname; Owner = Key; Position = presence.AbsolutePosition; Rotation = presence.Rotation; Velocity = presence.Velocity; Type = 0x01; // Avatar if (presence.Velocity != Vector3.Zero) { Type |= 0x02; // Active } Group = presence.ControllingClient.ActiveGroupId; } else //object { part = part.ParentGroup.RootPart; // We detect objects only LinkNum = 0; // Not relevant Group = part.GroupID; Name = part.Name; Owner = part.OwnerID; if (part.Velocity == Vector3.Zero) { Type = 0x04; // Passive } else { Type = 0x02; // Passive } foreach (SceneObjectPart p in part.ParentGroup.Children.Values) { if (p.Inventory.ContainsScripts()) { Type |= 0x08; // Scripted break; } } Position = part.AbsolutePosition; Quaternion wr = part.ParentGroup.GroupRotation; Rotation = wr; Velocity = part.Velocity; } }
public CameraControl() { m_heading = new OMV.Quaternion(OMV.Vector3.UnitY, 0f); m_globalPosition = new OMV.Vector3d(0d, 20d, 30d); // World coordinates (Z up) m_zoom = 1.0f; m_far = 300.0f; m_yawFixed = true; }
public LSL_List modInvokeL(string fname, params object[] parms) { // m_log.DebugFormat( // "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", // fname, // string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), // ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(object[])) { MODError(String.Format("return type mismatch for {0}", fname)); } object[] result = (object[])modInvoke(fname, parms); object[] llist = new object[result.Length]; for (int i = 0; i < result.Length; i++) { if (result[i] is string) { llist[i] = new LSL_String((string)result[i]); } else if (result[i] is int) { llist[i] = new LSL_Integer((int)result[i]); } else if (result[i] is float) { llist[i] = new LSL_Float((float)result[i]); } else if (result[i] is double) { llist[i] = new LSL_Float((double)result[i]); } else if (result[i] is UUID) { llist[i] = new LSL_Key(result[i].ToString()); } else if (result[i] is OpenMetaverse.Vector3) { OpenMetaverse.Vector3 vresult = (OpenMetaverse.Vector3)result[i]; llist[i] = new LSL_Vector(vresult.X, vresult.Y, vresult.Z); } else if (result[i] is OpenMetaverse.Quaternion) { OpenMetaverse.Quaternion qresult = (OpenMetaverse.Quaternion)result[i]; llist[i] = new LSL_Rotation(qresult.X, qresult.Y, qresult.Z, qresult.W); } else { MODError(String.Format("unknown list element {1} returned by {0}", fname, result[i].GetType().Name)); } } return(new LSL_List(llist)); }
public RenderableInfo() { basicObject = null; RegionRoot = null; // parentID = 0; parentEntity = null; position = OMV.Vector3.Zero; rotation = new OMV.Quaternion(0f, 0f, 0f, 0f); scale = new OMV.Vector3(1f, 1f, 1f); }
// rotate the camera by the given quaternion public void rotate(OMV.Quaternion rot) { rot.Normalize(); m_heading = rot * m_heading; if (OnCameraUpdate != null) { OnCameraUpdate(this); } }
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) : base(parent_scene, localID, avName, "BSCharacter") { _physicsActorType = (int)ActorTypes.Agent; _position = pos; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. _size = size; if (_size.X == 0f) { _size.X = BSParam.AvatarCapsuleDepth; } if (_size.Y == 0f) { _size.Y = BSParam.AvatarCapsuleWidth; } // A motor to control the acceleration and deceleration of the avatar movement. // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); // Infinite decay and timescale values so motor only changes current to target values. _velocityMotor = new BSVMotor("BSCharacter.Velocity", 0.2f, // time scale BSMotor.Infinite, // decay time scale BSMotor.InfiniteVector, // friction timescale 1f // efficiency ); _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _appliedVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); _currentFriction = BSParam.AvatarStandingFriction; _avatarDensity = BSParam.AvatarDensity; // The dimensions of the avatar capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject("BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into PhysBody and PhysShape PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); SetPhysicalProperties(); }); return; }
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) : base(parent_scene, localID, avName, "BSCharacter") { _physicsActorType = (int)ActorTypes.Agent; _isPhysical = true; _position = pos; _flying = isFlying; _orientation = OMV.Quaternion.Identity; RawVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. _size = size; if (_size.X == 0f) { _size.X = BSParam.AvatarCapsuleDepth; } if (_size.Y == 0f) { _size.Y = BSParam.AvatarCapsuleWidth; } // The dimensions of the physical capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. Scale = ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); // The avatar's movement is controlled by this motor that speeds up and slows down // the avatar seeking to reach the motor's target speed. // This motor runs as a prestep action for the avatar so it will keep the avatar // standing as well as moving. Destruction of the avatar will destroy the pre-step action. m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName); PhysicalActors.Add(AvatarMoveActorName, m_moveActor); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, Density, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject(LocalID, "BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into PhysBody and PhysShape PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); SetPhysicalProperties(); SubscribeEvents(1000); }); return; }
public static void AddPositionToHash(BHasher hasher, OMV.Vector3 pos, OMV.Quaternion rot) { hasher.Add(pos.X); hasher.Add(pos.Y); hasher.Add(pos.Z); hasher.Add(rot.X); hasher.Add(rot.Y); hasher.Add(rot.Z); hasher.Add(rot.W); }
// Add another level of parenting public InvertedMesh AddDisplayableLevel(InvertedMesh imesh, Displayable pDisp, DisplayableRenderable pDispRend) { InvertedMesh newIMesh = new InvertedMesh(imesh.containingScene, imesh.containingInstance, imesh.containingDisplayable, imesh.containingDisplayableRenderable, imesh.renderableMesh); globalPosition += pDisp.offsetPosition; globalRotation *= pDisp.offsetRotation; newIMesh.containingDisplayable = pDisp; newIMesh.containingDisplayableRenderable = pDispRend; return(newIMesh); }
public InvertedMesh(BScene pBs, BInstance pInst, Displayable pDisp, DisplayableRenderable pDisprend, RenderableMesh pRm) { containingScene = pBs; containingInstance = pInst; containingDisplayable = pDisp; containingDisplayableRenderable = pDisprend; renderableMesh = pRm; // Compute the global position of the Displayable globalPosition = containingDisplayable.offsetPosition * containingInstance.Rotation + containingInstance.Position; globalRotation = containingDisplayable.offsetRotation * containingInstance.Rotation; }
/// <summary> /// Update both position and heading with one call. Remember that the position /// is a global position. /// </summary> /// <param name="pos"></param> /// <param name="heading"></param> public void Update(OMV.Vector3d pos, OMV.Quaternion heading) { bool changed = (m_heading != heading) | (m_globalPosition != pos); m_globalPosition = pos; m_heading = heading; if (changed && (OnCameraUpdate != null)) { OnCameraUpdate(this); } }
// Rotate a vector by a quaternian public static OMV.Vector3 RotateVector(OMV.Quaternion q, OMV.Vector3 v) { OMV.Vector3 v2, v3; q.Normalize(); OMV.Vector3 qv = new OMV.Vector3(q.X, q.Y, q.Z); v2 = OMV.Vector3.Cross(qv, v); v3 = OMV.Vector3.Cross(qv, v2); v2 *= (2.0f * q.W); v3 *= 2.0f; return(v + v2 + v3); }
public void at_rot_target(UUID scriptID, uint handle, OpenMetaverse.Quaternion targetrot, OpenMetaverse.Quaternion atrot) { PostScriptEvent(scriptID, new EventParams( "at_rot_target", new object[] { new LSL_Integer(handle), new LSL_Rotation(targetrot.X, targetrot.Y, targetrot.Z, targetrot.W), new LSL_Rotation(atrot.X, atrot.Y, atrot.Z, atrot.W) }, zeroDetectParams)); }
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { Linkset = BSLinkset.Factory(PhysScene, this); PhysScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate() { Linkset.Refresh(this); }); }
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { // Default linkset implementation for this prim LinksetType = (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation; Linkset = BSLinkset.Factory(PhysScene, this); Linkset.Refresh(this); }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. PositionSanityCheck(true); if (_velocityMotor.Enabled) { // TODO: Decide if the step parameters should be changed depending on the avatar's // state (flying, colliding, ...). OMV.Vector3 stepVelocity = _velocityMotor.Step(PhysicsScene.LastTimeStep); // If falling, we keep the world's downward vector no matter what the other axis specify. if (!Flying && !IsColliding) { stepVelocity.Z = entprop.Velocity.Z; DetailLog("{0},BSCharacter.UpdateProperties,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity); } // If the user has said stop and we've stopped applying velocity correction, // the motor can be turned off. Set the velocity to zero so the zero motion is sent to the viewer. if (_velocityMotor.TargetValue.ApproxEquals(OMV.Vector3.Zero, 0.01f) && _velocityMotor.ErrorIsZero) { ZeroMotion(true); stepVelocity = OMV.Vector3.Zero; _velocityMotor.Enabled = false; DetailLog("{0},BSCharacter.UpdateProperties,taint,disableVelocityMotor,m={1}", LocalID, _velocityMotor); } _velocity = stepVelocity; entprop.Velocity = _velocity; BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); } // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; // Tell the linkset about value changes Linkset.UpdateProperties(this, true); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); }
public LSL_Rotation modInvokeR(string fname, params object[] parms) { Type returntype = m_comms.LookupReturnType(fname); if (returntype != typeof(OpenMetaverse.Quaternion)) { MODError(String.Format("return type mismatch for {0}", fname)); } OpenMetaverse.Quaternion result = (OpenMetaverse.Quaternion)modInvoke(fname, parms); return(new LSL_Rotation(result.X, result.Y, result.Z, result.W)); }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { // Don't change position if standing on a stationary object. if (!IsStationary) { _position = entprop.Position; } _orientation = entprop.Rotation; if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) && Velocity != OMV.Vector3.Zero) { entprop.Velocity = OMV.Vector3.Zero; entprop.Acceleration = OMV.Vector3.Zero; entprop.RotationalVelocity = OMV.Vector3.Zero; Velocity = OMV.Vector3.Zero; TriggerSignificantMovement(); TriggerMovementUpdate(); } if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.4f)) { RawVelocity = entprop.Velocity; TriggerSignificantMovement(); TriggerMovementUpdate(); } _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) { DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); entprop.Position = _position; } // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; // Tell the linkset about value changes // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity); }
public static float[] ComposeMatrix4(OMV.Vector3 pos, OMV.Quaternion rot) { float[] aPos = new float[3] { pos.X, pos.Y, pos.Z }; float[] aRot = new float[4] { rot.X, rot.Y, rot.Z, rot.W }; float[] aScale = new float[3] { 1.0f, 1.0f, 1.0f }; return(Utilities.ComposeMatrix4(aPos, aRot, aScale)); }
// Convert the positions and all the vertices in an ExtendedPrim from one // coordinate space to another. ExtendedPrim.coordSpace gives the current // coordinates and we specify a new one here. // This is not a general solution -- it pretty much only works to convert // right-handed,Z-up coordinates (OpenSimulator) to right-handed,Y-up // (OpenGL). public static void FixCoordinates(BInstance inst, CoordAxis newCoords) { if (inst.coordAxis.system != newCoords.system) { OMV.Matrix4 coordTransform = OMV.Matrix4.Identity; OMV.Quaternion coordTransformQ = OMV.Quaternion.Identity; if (inst.coordAxis.getUpDimension == CoordAxis.Zup && newCoords.getUpDimension == CoordAxis.Yup) { // The one thing we know to do is change from Zup to Yup coordTransformQ = OMV.Quaternion.CreateFromAxisAngle(1.0f, 0.0f, 0.0f, -(float)Math.PI / 2f); // Make a clean matrix version. // The libraries tend to create matrices with small numbers (1.119093e-07) for zero. coordTransform = new OMV.Matrix4( 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1); } OMV.Vector3 oldPos = inst.Position; // DEBUG DEBUG OMV.Quaternion oldRot = inst.Rotation; // DEBUG DEBUG // Fix the location in space inst.Position = inst.Position * coordTransformQ; inst.Rotation = coordTransformQ * inst.Rotation; inst.coordAxis = newCoords; // ConvOAR.Globals.log.DebugFormat("{0} FixCoordinates. dispID={1}, oldPos={2}, newPos={3}, oldRot={4}, newRot={5}", // _logHeader, inst.handle, oldPos, inst.Position, oldRot, inst.Rotation); // Go through all the vertices and change the UV coords if necessary List <MeshInfo> meshInfos = CollectMeshesFromDisplayable(inst.Representation); meshInfos.ForEach(meshInfo => { if (meshInfo.coordAxis.getUVOrigin != newCoords.getUVOrigin) { for (int ii = 0; ii < meshInfo.vertexs.Count; ii++) { var vert = meshInfo.vertexs[ii]; vert.TexCoord.Y = 1f - vert.TexCoord.Y; meshInfo.vertexs[ii] = vert; } meshInfo.coordAxis = newCoords; } }); } else { ConvOAR.Globals.log.DebugFormat("FixCoordinates. Not converting coord system. dispID={0}", inst.handle); } }
// 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape) public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement) { // Each child position and rotation is given relative to the center-of-mass. OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation); OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation; OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation; // Save relative position for recomputing child's world position after moving linkset. Index = indx; OffsetFromRoot = displacementFromRoot; OffsetFromCenterOfMass = displacementFromCOM; OffsetRot = displacementRot; }
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical, int material, float friction, float restitution, float gravityMultiplier, float density) : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical) { // Default linkset implementation for this prim LinksetType = (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation; Linkset = BSLinkset.Factory(PhysicsScene, this); if (Linkset != null) { Linkset.Refresh(this); } }
public DetectParams() { Key = UUID.Zero; OffsetPos = new OpenMetaverse.Vector3(); LinkNum = 0; Group = UUID.Zero; Name = String.Empty; Owner = UUID.Zero; Position = new OpenMetaverse.Vector3(); Rotation = new OpenMetaverse.Quaternion(); Type = 0; Velocity = new OpenMetaverse.Vector3(); initializeSurfaceTouch(); }
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) : base(parent_scene, localID, avName, "BSCharacter") { _physicsActorType = (int)ActorTypes.Agent; _isPhysical = true; _position = pos; _flying = isFlying; _orientation = OMV.Quaternion.Identity; RawVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. _size = size; if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; // The dimensions of the physical capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. Scale = ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); // The avatar's movement is controlled by this motor that speeds up and slows down // the avatar seeking to reach the motor's target speed. // This motor runs as a prestep action for the avatar so it will keep the avatar // standing as well as moving. Destruction of the avatar will destroy the pre-step action. m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName); PhysicalActors.Add(AvatarMoveActorName, m_moveActor); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, Density, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject(LocalID, "BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into PhysBody and PhysShape PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); SetPhysicalProperties(); SubscribeEvents(1000); }); return; }
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) { base.BaseInitialize(parent_scene, localID, avName, "BSCharacter"); _physicsActorType = (int)ActorTypes.Agent; _position = pos; _size = size; _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); // The dimensions of the avatar capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. ComputeAvatarScale(_size); _avatarDensity = PhysicsScene.Params.avatarDensity; // set _avatarVolume and _mass based on capsule size, _density and _scale ComputeAvatarVolumeAndMass(); ShapeData shapeData = new ShapeData(); shapeData.ID = LocalID; shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; shapeData.Position = _position; shapeData.Rotation = _orientation; shapeData.Velocity = _velocity; shapeData.Scale = _scale; shapeData.Mass = _mass; shapeData.Buoyancy = _buoyancy; shapeData.Static = ShapeData.numericFalse; shapeData.Friction = PhysicsScene.Params.avatarFriction; shapeData.Restitution = PhysicsScene.Params.avatarRestitution; // do actual create at taint time PhysicsScene.TaintedObject("BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData); // Set the buoyancy for flying. This will be refactored when all the settings happen in C#. // If not set at creation, the avatar will stop flying when created after crossing a region boundry. BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID)); // This works here because CreateObject has already put the character into the physical world. BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask); }); return; }
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) : base(parent_scene, localID, avName, "BSCharacter") { _physicsActorType = (int)ActorTypes.Agent; _position = pos; _flying = isFlying; _orientation = OMV.Quaternion.Identity; _velocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor; // Old versions of ScenePresence passed only the height. If width and/or depth are zero, // replace with the default values. _size = size; if (_size.X == 0f) _size.X = BSParam.AvatarCapsuleDepth; if (_size.Y == 0f) _size.Y = BSParam.AvatarCapsuleWidth; // The dimensions of the physical capsule are kept in the scale. // Physics creates a unit capsule which is scaled by the physics engine. Scale = ComputeAvatarScale(_size); // set _avatarVolume and _mass based on capsule size, _density and Scale ComputeAvatarVolumeAndMass(); SetupMovementMotor(); DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", LocalID, _size, Scale, Density, _avatarVolume, RawMass); // do actual creation in taint time PhysicsScene.TaintedObject("BSCharacter.create", delegate() { DetailLog("{0},BSCharacter.create,taint", LocalID); // New body and shape into PhysBody and PhysShape PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); SetPhysicalProperties(); }); return; }
public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(parent_scene, localID, primName, "BSPrim") { // MainConsole.Instance.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); _physicsActorType = (int)ActorTypes.Prim; _position = pos; _size = size; Scale = size; // prims are the size the user wants them to be (different for BSCharactes). _orientation = rotation; _buoyancy = 0f; RawVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; BaseShape = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; // Add a dynamic vehicle to our set of actors that can move this prim. VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName); PhysicalActors.Add(VehicleActorName, VehicleActor); //PhysicalActors.Add(VehicleActorName, new BSDynamics(PhysicsScene, this, VehicleActorName)); _mass = CalculateMass(); // DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject(LocalID, "BSPrim.create", delegate() { // Make sure the object is being created with some sanity. ExtremeSanityCheck(true /* inTaintTime */); CreateGeomAndObject(true); CurrentCollisionFlags = PhysicsScene.PE.GetCollisionFlags(PhysBody); IsInitialized = true; }); }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { bool needSendUpdate = false; // Don't change position if standing on a stationary object. if (!IsStationary) _position = entprop.Position; _orientation = entprop.Rotation; if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) && Velocity != OMV.Vector3.Zero) { entprop.Velocity = OMV.Vector3.Zero; entprop.Acceleration = OMV.Vector3.Zero; entprop.RotationalVelocity = OMV.Vector3.Zero; Velocity = OMV.Vector3.Zero; m_ZeroUpdateSent = 3; needSendUpdate = true; } if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.4f)) { RawVelocity = entprop.Velocity; needSendUpdate = true; } // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) { DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); entprop.Position = _position; } // animation checks const float POSITION_TOLERANCE = 5.0f; float VELOCITY_TOLERANCE = 0.025f * 0.025f; if (PhysicsScene.TimeDilation < 0.5) { float percent = (1f - PhysicsScene.TimeDilation) * 100; VELOCITY_TOLERANCE *= percent*2; } bool VelIsZero = false; OMV.Vector3 _velocity = Velocity; int vcntr = 0; if (Math.Abs(_velocity.X) < 0.01) { vcntr++; _velocity.X = 0; } if (Math.Abs(_velocity.Y) < 0.01) { vcntr++; _velocity.Y = 0; } if (Math.Abs(_velocity.Z) < 0.01) { vcntr++; _velocity.Z = 0; } if (vcntr == 3) { Velocity = _velocity; VelIsZero = true; } float vlength = (Velocity - m_lastVelocity).LengthSquared(); float plength = (_position - m_lastPosition).LengthSquared(); if ( vlength > VELOCITY_TOLERANCE || plength > POSITION_TOLERANCE ) { needSendUpdate = true; m_ZeroUpdateSent = 3; } else if (VelIsZero) { if (m_ZeroUpdateSent > 0) { needSendUpdate = true; m_ZeroUpdateSent--; } } if (needSendUpdate) { m_lastPosition = _position; m_lastVelocity = Velocity; TriggerSignificantMovement(); TriggerMovementUpdate(); // remember the current and last set values _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; } // Tell the linkset about value changes // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity); }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. PositionSanityCheck(true); // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; // Tell the linkset about value changes Linkset.UpdateProperties(this, true); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); }
/// <summary> /// rotate the specified amounts around the camera's local axis /// </summary> /// <param name="X"></param> /// <param name="Y"></param> /// <param name="Z"></param> public void rotate(float X, float Y, float Z) { if (YawFixed) { // some of the rotation is around X OMV.Quaternion xvec = OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitX, X); xvec.Normalize(); // some of the rotation is around Z OMV.Quaternion zvec = OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitZ, Z); zvec.Normalize(); m_heading = zvec * m_heading; m_heading = m_heading * xvec; } else { OMV.Quaternion rot = new OMV.Quaternion(X, Y, Z); rot.Normalize(); rotate(rot); } }
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation) //To be removed { return AddPrimShape(primName, pbs, position, size, rotation, false); }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { // Don't change position if standing on a stationary object. if (!IsStationary) _position = entprop.Position; _orientation = entprop.Rotation; if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) && Velocity != OMV.Vector3.Zero) { entprop.Velocity = OMV.Vector3.Zero; entprop.Acceleration = OMV.Vector3.Zero; entprop.RotationalVelocity = OMV.Vector3.Zero; Velocity = OMV.Vector3.Zero; TriggerSignificantMovement(); TriggerMovementUpdate(); } if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.4f)) { RawVelocity = entprop.Velocity; TriggerSignificantMovement(); TriggerMovementUpdate(); } _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) { DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); entprop.Position = _position; } // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; // Tell the linkset about value changes // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // base.RequestPhysicsterseUpdate(); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity); }
private PhysicsActor AddPrim(Vector3 position, Vector3 size, Quaternion rotation) { Vec3 pos = new Vec3(); pos.X = position.X; pos.Y = position.Y; pos.Z = position.Z; Vec3 siz = new Vec3(); siz.X = size.X; siz.Y = size.Y; siz.Z = size.Z; PhysXPrim act = new PhysXPrim(scene.AddNewBox(pos, siz)); _prims.Add(act); return act; }
public override void UpdateProperties(EntityProperties entprop) { // Updates only for individual prims and for the root object of a linkset. if (Linkset.IsRoot(this)) { // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet // TODO: handle physics introduced by Bullet with computed vehicle physics. if (_vehicle.IsActive) { entprop.RotationalVelocity = OMV.Vector3.Zero; } // Assign directly to the local variables so the normal set action does not happen _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // The sanity check can change the velocity and/or position. if (IsPhysical && PositionSanityCheck(true)) { entprop.Position = _position; entprop.Velocity = _velocity; } OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}", LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity); // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; base.RequestPhysicsterseUpdate(); } /* else { // For debugging, report the movement of children DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } */ // The linkset implimentation might want to know about this. Linkset.UpdateProperties(this, true); }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. TriggerPreUpdatePropertyAction(ref entprop); // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG // Assign directly to the local variables so the normal set actions do not happen _position = entprop.Position; _orientation = entprop.Rotation; bool terseUpdate = false; if (entprop.Velocity != OMV.Vector3.Zero && entprop.Velocity.ApproxEquals(OMV.Vector3.Zero, 0.01f) && Velocity != OMV.Vector3.Zero) { entprop.Velocity = OMV.Vector3.Zero; entprop.Acceleration = OMV.Vector3.Zero; entprop.RotationalVelocity = OMV.Vector3.Zero; Velocity = RawVelocity = OMV.Vector3.Zero; ZeroMotion(true); terseUpdate = true; } // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // very sensitive to velocity changes. if (entprop.Velocity == OMV.Vector3.Zero || (VehicleType != 0 /*&& !entprop.Velocity.ApproxEquals(RawVelocity, 0.01f)*/) || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold / 2f)) { terseUpdate = true; RawVelocity = entprop.Velocity; } _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // The sanity check can change the velocity and/or position. if (PositionSanityCheck(true /* inTaintTime */ )) { entprop.Position = _position; entprop.Velocity = RawVelocity; entprop.RotationalVelocity = _rotationalVelocity; entprop.Acceleration = _acceleration; } // 20131224 not used OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG //DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; if (terseUpdate) base.RequestPhysicsterseUpdate(); /* else { // For debugging, report the movement of children DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, entprop.Acceleration, entprop.RotationalVelocity); } */ }
public void UpdateProperties(EntityProperties entprop) { UpdatedProperties changed = 0; if (SHOULD_DAMP_UPDATES) { // assign to the local variables so the normal set action does not happen // if (_position != entprop.Position) if (!_position.ApproxEquals(entprop.Position, POSITION_TOLERANCE)) { _position = entprop.Position; // m_log.DebugFormat("{0}: UpdateProperties: id={1}, pos = {2}", LogHeader, LocalID, _position); changed |= UpdatedProperties.Position; } // if (_orientation != entprop.Rotation) if (!_orientation.ApproxEquals(entprop.Rotation, ROTATION_TOLERANCE)) { _orientation = entprop.Rotation; // m_log.DebugFormat("{0}: UpdateProperties: id={1}, rot = {2}", LogHeader, LocalID, _orientation); changed |= UpdatedProperties.Rotation; } // if (_velocity != entprop.Velocity) if (!_velocity.ApproxEquals(entprop.Velocity, VELOCITY_TOLERANCE)) { _velocity = entprop.Velocity; // m_log.DebugFormat("{0}: UpdateProperties: velocity = {1}", LogHeader, _velocity); changed |= UpdatedProperties.Velocity; } // if (_acceleration != entprop.Acceleration) if (!_acceleration.ApproxEquals(entprop.Acceleration, ACCELERATION_TOLERANCE)) { _acceleration = entprop.Acceleration; // m_log.DebugFormat("{0}: UpdateProperties: acceleration = {1}", LogHeader, _acceleration); changed |= UpdatedProperties.Acceleration; } // if (_rotationalVelocity != entprop.RotationalVelocity) if (!_rotationalVelocity.ApproxEquals(entprop.RotationalVelocity, ROTATIONAL_VELOCITY_TOLERANCE)) { _rotationalVelocity = entprop.RotationalVelocity; // m_log.DebugFormat("{0}: UpdateProperties: rotationalVelocity = {1}", LogHeader, _rotationalVelocity); changed |= UpdatedProperties.RotationalVel; } if (changed != 0) { // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); // Only update the position of single objects and linkset roots if (this._parentPrim == null) { // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); base.RequestPhysicsterseUpdate(); } } } else { // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. // Only updates only for individual prims and for the root object of a linkset. if (this._parentPrim == null) { // Assign to the local variables so the normal set action does not happen _position = entprop.Position; _orientation = entprop.Rotation; _velocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); base.RequestPhysicsterseUpdate(); } } }
public BasicActor(BasicScene scene, float height, float radius, OpenMetaverse.Vector3 position, OpenMetaverse.Quaternion rotation, bool flying, OpenMetaverse.Vector3 initialVelocity) { _scene = scene; _radius = Math.Max(radius, 0.2f); /* * The capsule is defined as a position, a vertical height, and a radius. The height is the distance between the * two sphere centers at the end of the capsule. In other words: * * p = pos (returned by controller) * h = height * r = radius * * p = center of capsule * top sphere center = p.z + h*0.5 * bottom sphere center = p.z - h*0.5 * top capsule point = p.z + h*0.5 + r * bottom capsule point = p.z - h*0.5 - r */ _height = height; _flying = flying; float volume = (float)(Math.PI * Math.Pow(_radius, 2) * this.CapsuleHeight); _mass = CHARACTER_DENSITY * volume; _position = position; _rotation = rotation; DoZDepenetration(); _lastSync = (uint)Environment.TickCount; _vTarget = initialVelocity; _velocity = initialVelocity; if (_vTarget != OpenMetaverse.Vector3.Zero) { //hack to continue at velocity until the controller picks up _lastVelocityNonZero = OpenSim.Framework.Util.GetLongTickCount() - VELOCITY_RAMPUP_TIME; } }
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical) { return AddPrim(position, size, rotation); }
public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) : base(parent_scene, localID, primName, "BSPrim") { // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); _physicsActorType = (int)ActorTypes.Prim; _position = pos; _size = size; Scale = size; // prims are the size the user wants them to be (different for BSCharactes). _orientation = rotation; _buoyancy = 1f; _velocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; BaseShape = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; // Someday set default attributes based on the material but, for now, we don't know the prim material yet. // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical); _density = PhysicsScene.Params.defaultDensity; _friction = PhysicsScene.Params.defaultFriction; _restitution = PhysicsScene.Params.defaultRestitution; _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness _mass = CalculateMass(); Linkset.Refresh(this); DetailLog("{0},BSPrim.constructor,call", LocalID); // do the actual object creation at taint time PhysicsScene.TaintedObject("BSPrim.create", delegate() { CreateGeomAndObject(true); CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(PhysBody.ptr); }); }
// ========================================================================== /// <summary> /// Update the camera. The coordinate system from the EntityCamera is LL's /// (Z up). We have to convert the rotation and position to Ogre coords /// (Y up). /// </summary> /// <param name="cam"></param> // private bool haveAttachedCamera = false; public void UpdateCamera(CameraControl cam) { /* Historical Note: This is part of code to attach the camera to the avatar. When this was written * the avatar code was not in place so the actual scene node to attach the camera too is problematic. * Fix this when there is an avatar. if (!haveAttachedCamera && cam.AssociatedAgent != null && cam.AssociatedAgent.AssociatedAvatar != null) { m_log.Log(LogLevel.DVIEWDETAIL, "OnAgentUpdate: Attaching camera with {0}", cam.AssociatedAgent.AssociatedAvatar.Name); haveAttachedCamera = Ogr.AttachCamera(cam.AssociatedAgent.AssociatedAvatar.Name.Name, 1.0f, 0.0f, 1.0f, 0f, 0f, 0f, 1f); } */ // OMV.Quaternion orient = new OMV.Quaternion(OMV.Vector3.UnitX, -Constants.PI / 2) // * new OMV.Quaternion(OMV.Vector3.UnitZ, -Constants.PI / 2) // * cam.Direction; // we need to rotate the camera 90 to make it work out in Ogre. Not sure why. // OMV.Quaternion orient = cam.Heading * OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitZ, -Constants.PI / 2); OMV.Quaternion orient = OMV.Quaternion.CreateFromAxisAngle(OMV.Vector3.UnitZ, -Constants.PI / 2) * cam.Heading; // OMV.Quaternion orient = cam.Heading; orient.Normalize(); m_lastCameraPosition = cam.GlobalPosition; m_lastCameraOrientation = orient; // note the conversion from LL coordinates (Z up) to Ogre coordinates (Y up) OMV.Vector3d pos = cam.GlobalPosition * m_sceneMagnification; Ogr.UpdateCameraBF(pos.X, pos.Z, -pos.Y, orient.W, orient.X, orient.Z, -orient.Y, 1.0f, (float)cam.Far*m_sceneMagnification, 1.0f); // m_log.Log(LogLevel.DRENDERDETAIL, "UpdateCamera: Camera to p={0}, r={1}", pos, orient); return; }
public override void VehicleRotationParam(int param, Quaternion rotation) { }
// The physics engine says that properties have updated. Update same and inform // the world that things have changed. public override void UpdateProperties(EntityProperties entprop) { // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. TriggerPreUpdatePropertyAction(ref entprop); // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG // Assign directly to the local variables so the normal set actions do not happen _position = entprop.Position; _orientation = entprop.Rotation; // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // very sensitive to velocity changes. if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) RawVelocity = entprop.Velocity; _acceleration = entprop.Acceleration; _rotationalVelocity = entprop.RotationalVelocity; // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // The sanity check can change the velocity and/or position. if (PositionSanityCheck(true /* inTaintTime */ )) { entprop.Position = _position; entprop.Velocity = RawVelocity; entprop.RotationalVelocity = _rotationalVelocity; entprop.Acceleration = _acceleration; } OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); // remember the current and last set values LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; // Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims. base.RequestPhysicsterseUpdate(); }
public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) { // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); _localID = localID; _avName = primName; _scene = parent_scene; _position = pos; _size = size; _scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type _orientation = rotation; _buoyancy = 1f; _velocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; _angularVelocity = OMV.Vector3.Zero; _hullKey = 0; _meshKey = 0; _pbs = pbs; _isPhysical = pisPhysical; _isVolumeDetect = false; _subscribedEventsMs = 0; _friction = _scene.Params.defaultFriction; // TODO: compute based on object material _density = _scene.Params.defaultDensity; // TODO: compute based on object material _restitution = _scene.Params.defaultRestitution; _parentPrim = null; // not a child or a parent _vehicle = new BSDynamics(this); // add vehicleness _childrenPrims = new List<BSPrim>(); if (_isPhysical) _mass = CalculateMass(); else _mass = 0f; // do the actual object creation at taint time _scene.TaintedObject(delegate() { RecreateGeomAndObject(); }); }
internal void MetricsInit(float timeStep, OpenMetaverse.Quaternion vframe, OpenMetaverse.Quaternion rotation, OpenMetaverse.Vector3 worldAngularVel, OpenMetaverse.Vector3 worldLinearVel, OpenMetaverse.Vector3 localAngularVel, OpenMetaverse.Vector3 localLinearVel) { this.timeStep = timeStep; this.vframe = vframe; this.rotation = rotation; this.worldAngularVel = worldAngularVel; this.worldLinearVel = worldLinearVel; this.localAngularVel = localAngularVel; this.localLinearVel = localLinearVel; }
public BSPrim(ISceneChildEntity entity, bool isPhysical, BSScene parent_scene) { _parent_entity = entity; // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); _localID = _parent_entity.LocalId; _avName = _parent_entity.Name; _scene = parent_scene; _position = _parent_entity.AbsolutePosition; _size = _parent_entity.Scale; _scale = new OMV.Vector3(1f, 1f, 1f); // the scale will be set by CreateGeom depending on object type _orientation = _parent_entity.Rotation; _buoyancy = 1f; _velocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; _angularVelocity = OMV.Vector3.Zero; _hullKey = 0; _pbs = _parent_entity.Shape; _isPhysical = isPhysical; _isVolumeDetect = _parent_entity.VolumeDetectActive; _subscribedEventsMs = 0; _parentPrim = null; _vehicle = new BSDynamics(this); _childrenPrims = new List<BSPrim>(); if (_isPhysical) _mass = CalculateMass(); else _mass = 0f; // do the actual object creation at taint time _scene.TaintedObject(delegate() { RecreateGeomAndObject(); }); }
// // Main simulation entry point, called every physics frame (nominally 64x/sec). // This is a pipelined simulation, several physical events happen at the same time, and // the results of the previous physics frame feed forward into the next frame. // internal void Simulate(float timeStep, uint frameNum) { if (_props.Type == VehicleType.None) return; // If the vehicle's oriented bounding box is null, request it now. // This could end up null ayway, but the subsequent code checks for that possibility. if (_actor.OBBobject == null) { _actor.OBBobject = _actor.DoRequestOBB(); } // Tick smoothing. Under even light loads, the timestep bobbles between 1 and 2 physics frames, // sufficiently often that it noticibly affects the movement timings. This smoothing cleans up the glitches. // This performs a weighted average of this frame's timestep and the one in the previous frame. timeStep = _props.Dynamics.Timestep * 0.8f + timeStep * 0.2f; //handle a race condition where a physics state save happened after the vehicle type has been //set, but before physics got a chance to set the default properties if (_props.ParamsRot.Count == 0) { m_log.InfoFormat("[VehicleSimulate] race condition"); SetVehicleDefaults(_props); SetVehicleDefaultActions(); } // Debug params every 10ish seconds. if (VehicleLimits.DebugPrintParams && (frameNum % 600) == 0) { DisplayParameters(); } // Grab overrides vehicle movement. // If the vehicle is being grabbed skip the simulation, otherwise // severe squirming and tossing will happen. if (_actor.Properties.GrabTargetTau != 0) return; // Metrics: both world and local angular deltaV, linear deltaV vframe = _props.ParamsRot[RotationParams.VehicleReferenceFrame]; rotation = _actor.RotationUnsafe * vframe; // Safe from physics thread (as in this code) // A PhysX velocity behavior sends strong and opposite velocities when an object collides: e.g., -55,+55,=55,... // Per axis, when velocities are opposing, make a two-frame average to eliminate that physX jitter. // Angular if ((worldAngularVel.X * _actor.DynActorImpl.AngularVelocity.X) >= 0) worldAngularVel.X = _actor.DynActorImpl.AngularVelocity.X; else worldAngularVel.X = worldAngularVel.X * 0.5f + _actor.DynActorImpl.AngularVelocity.X * 0.5f; if ((worldAngularVel.Y * _actor.DynActorImpl.AngularVelocity.Y) >= 0) worldAngularVel.Y = _actor.DynActorImpl.AngularVelocity.Y; else worldAngularVel.Y = worldAngularVel.Y * 0.5f + _actor.DynActorImpl.AngularVelocity.Y * 0.5f; if ((worldAngularVel.Z * _actor.DynActorImpl.AngularVelocity.Z) >= 0) worldAngularVel.Z = _actor.DynActorImpl.AngularVelocity.Z; else worldAngularVel.Z = worldAngularVel.Z * 0.5f + _actor.DynActorImpl.AngularVelocity.Z * 0.5f; //Linear if ((worldLinearVel.X * _actor.DynActorImpl.LinearVelocity.X) >= 0) worldLinearVel.X = _actor.DynActorImpl.LinearVelocity.X; else worldLinearVel.X = worldLinearVel.X * 0.5f + _actor.DynActorImpl.LinearVelocity.X * 0.5f; if ((worldLinearVel.Y * _actor.DynActorImpl.LinearVelocity.Y) >= 0) worldLinearVel.Y = _actor.DynActorImpl.LinearVelocity.Y; else worldLinearVel.Y = worldLinearVel.Y * 0.5f + _actor.DynActorImpl.LinearVelocity.Y * 0.5f; if ((worldLinearVel.Z * _actor.DynActorImpl.LinearVelocity.Z) >= 0) worldLinearVel.Z = _actor.DynActorImpl.LinearVelocity.Z; else worldLinearVel.Z = worldLinearVel.Z * 0.5f + _actor.DynActorImpl.LinearVelocity.Z * 0.5f; localAngularVel = worldAngularVel * OpenMetaverse.Quaternion.Inverse(rotation); localLinearVel = worldLinearVel * OpenMetaverse.Quaternion.Inverse(rotation); //m_log.DebugFormat("[Vehicle Simulate] lvel={0} lspd={1} step={2} frame={3}", localLinearVel, localLinearVel, timeStep, frameNum); // Region change check. If the region has changed, the stall detection logic has to be reset one // frame, and various vehicle actions (hover, buoyancy, etc.) have to be reestablished // Note that the local region field gets cleared on crossings since the object is actually getting recreated. // if (_scene.RegionID != _regionId) { if (VehicleLimits.DebugRegionChange) m_log.InfoFormat("[Vehicle Simulate] changed region: new={0}", _scene.RegionID); _regionId = _scene.RegionID; // Do this to prevent a phantom stall-detection at the crossing // object rez or object made physical. _props.Dynamics.LastAccessTOD = DateTime.Now; SetVehicleDefaultActions(); } // Reset motors if the time between calls is greater than one second. // This handles cases when the vehicle has been edited or rezzed. // It prevents the vehicle from taking off using stale forces. float actualstep = _motor.CheckResetMotors(timeStep); _motor.TorqueInit(); _motor.ClearLinearMotorStalled(); _props.Dynamics.Timestep = timeStep; // ------------------------------------------------------------------------------------------- // Mitigate a PhysX velocity spiking bug. // This has the side effect of changing the local velocities. // if (VehicleLimits.DoSpikeDetection) { MitigatePhysxSpiking(actualstep); } // Initialize the motor with the entry metrics. _motor.MetricsInit(timeStep, vframe, rotation, worldAngularVel, worldLinearVel, localAngularVel, localLinearVel); // ------------------------------------------------------------------------------------------- // Camera based movement: // SimulateCameraBasedMotorInput(timeStep, frameNum); // ------------------------------------------------------------------------------------------- // Build the wind direction data for this moment. // BuildWindData(timeStep, frameNum); // ------------------------------------------------------------------------------------------- // Ground penetration fix. A bug in PhysX permits a vehicle to punch through // the ground plane if sufficient force is present. When that happens, apply a very // strong upward force. This also fixes the case where someone edits/moves a physical vehicle below // ground, which can grief the region. // float gnd = _motor.GetGroundHeightBeneathVehicle(); if (_actor.Position.Z - gnd < VehicleLimits.MaxGroundPenetration) { OpenMetaverse.Vector3 zforce = OpenMetaverse.Vector3.Zero; zforce.Z = 1.0f + Math.Abs(localLinearVel.Z * 3.0f); _actor.DynActorImpl.AddForce(PhysUtil.OmvVectorToPhysx(zforce), PhysX.ForceMode.VelocityChange, true); } // ------------------------------------------------------------------------------------------- // Ground drag for boats - boats have differential friction. // SimulateBoatGroundDrag(timeStep); // ------------------------------------------------------------------------------------------- // Angular deflection - turning toward the direction of movement. // if (VehicleLimits.DoAngularDeflection) { SimulateAngularDeflection(timeStep); } // ------------------------------------------------------------------------------------------- // Linear deflection - changing direction of movement toward forward axis. // if (VehicleLimits.DoLinearDeflection) { SimulateLinearDeflection(timeStep); } // ------------------------------------------------------------------------------------------- // Sled movement - Motors are usually inoperative but a sled needs force assist on downslopes. // if (_props.Type == VehicleType.Sled) { SimulateSledMovement(timeStep); } // ------------------------------------------------------------------------------------------- // Vertical attractor - Pointing the local Z axis to the sky in the designated timescale. // Banking - induce yaw rotation (about the world z-axis) proportional to angle of roll (about the local x-axis). // OpenMetaverse.Vector3 attractionForces = OpenMetaverse.Vector3.Zero; if (VehicleLimits.DoVerticalAttractor) { float angle; bool inverted; SimulateVerticalAttractor(timeStep, frameNum, out attractionForces, out angle, out inverted); SimulateBankingToYaw(timeStep, angle, inverted); } // ------------------------------------------------------------------------------------------- // Wind forces // if ((_props.Flags & VehicleFlags.ReactToWind) != 0) { SimulateWindForces(timeStep); } // ------------------------------------------------------------------------------------------- // Motors // if (VehicleLimits.DoMotors) { _motor.Simulate(timeStep, frameNum, attractionForces); } // ------------------------------------------------------------------------------------------- // Angular Friction - apply inverse rotational velocity along each axis based on the friction timescales. // if (VehicleLimits.DoAngularFriction) { SimulateAngularFriction(timeStep); } // ------------------------------------------------------------------------------------------- // Linear Friction - apply inverse velocity along each axis based on the friction timescales. // if (VehicleLimits.DoLinearFriction) { SimulateLinearFriction(timeStep); } // Apply the accumulated torque _motor.TorqueFini(); // Save parameters to be fed forward and used in the next frame. _props.Dynamics.LastPosition = _actor.Position; _props.Dynamics.Timestep = timeStep; _props.Dynamics.LocalLinearVelocity = localLinearVel; _props.Dynamics.LocalAngularVelocity = localAngularVel; }