/// <summary> /// This creates the Avatar's physical Surrogate at the position supplied /// </summary> /// <param name="npositionX"></param> /// <param name="npositionY"></param> /// <param name="npositionZ"></param> // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only // place that is safe to call this routine AvatarGeomAndBodyCreation. private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) { if (CAPSULE_LENGTH <= 0) { m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); CAPSULE_LENGTH = 0.01f; } if (CAPSULE_RADIUS <= 0) { m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); CAPSULE_RADIUS = 0.01f; } Shell = new btCapsuleShape(CAPSULE_RADIUS, CAPSULE_LENGTH); if (m_bodyPosition == null) m_bodyPosition = new btVector3(npositionX, npositionY, npositionZ); m_bodyPosition.setValue(npositionX, npositionY, npositionZ); if (m_bodyOrientation == null) m_bodyOrientation = new btQuaternion(m_CapsuleOrientationAxis, (Utils.DEG_TO_RAD * 90)); if (m_bodyTransform == null) m_bodyTransform = new btTransform(m_bodyOrientation, m_bodyPosition); else { m_bodyTransform.Dispose(); m_bodyTransform = new btTransform(m_bodyOrientation, m_bodyPosition); } if (m_bodyMotionState == null) m_bodyMotionState = new btDefaultMotionState(m_bodyTransform); else m_bodyMotionState.setWorldTransform(m_bodyTransform); m_mass = Mass; Body = new btRigidBody(m_mass, m_bodyMotionState, Shell); // this is used for self identification. User localID instead of body handle Body.setUserPointer(new IntPtr((int)m_localID)); if (ClosestCastResult != null) ClosestCastResult.Dispose(); ClosestCastResult = new ClosestNotMeRayResultCallback(Body); m_parent_scene.AddRigidBody(Body); Body.setActivationState(4); if (m_aMotor != null) { if (m_aMotor.Handle != IntPtr.Zero) { m_parent_scene.getBulletWorld().removeConstraint(m_aMotor); m_aMotor.Dispose(); } m_aMotor = null; } m_aMotor = new btGeneric6DofConstraint(Body, m_parent_scene.TerrainBody, m_parent_scene.TransZero, m_parent_scene.TransZero, false); m_aMotor.setAngularLowerLimit(m_parent_scene.VectorZero); m_aMotor.setAngularUpperLimit(m_parent_scene.VectorZero); }
internal void EnableAxisMotor(Vector3 axislock) { if (m_aMotor != null) DisableAxisMotor(); if (Body == null) return; if (Body.Handle == IntPtr.Zero) return; if (AxisLockAngleHigh != null && AxisLockAngleHigh.Handle != IntPtr.Zero) AxisLockAngleHigh.Dispose(); m_aMotor = new btGeneric6DofConstraint(Body, _parent_scene.TerrainBody, _parent_scene.TransZero, _parent_scene.TransZero, false); float endNoLock = (360 * Utils.DEG_TO_RAD); AxisLockAngleHigh = new btVector3((axislock.X == 0) ? 0 : endNoLock, (axislock.Y == 0) ? 0 : endNoLock, (axislock.Z == 0) ? 0 : endNoLock); m_aMotor.setAngularLowerLimit(_parent_scene.VectorZero); m_aMotor.setAngularUpperLimit(AxisLockAngleHigh); m_aMotor.setLinearLowerLimit(AxisLockLinearLow); m_aMotor.setLinearUpperLimit(AxisLockLinearHigh); _parent_scene.getBulletWorld().addConstraint((btTypedConstraint)m_aMotor); //m_aMotor. }