Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
commit
551727cd19
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Information about this assembly is defined by the following
|
||||||
|
// attributes.
|
||||||
|
//
|
||||||
|
// change them to the information which is associated with the assembly
|
||||||
|
// you compile.
|
||||||
|
|
||||||
|
[assembly : AssemblyTitle("OdePlugin")]
|
||||||
|
[assembly : AssemblyDescription("")]
|
||||||
|
[assembly : AssemblyConfiguration("")]
|
||||||
|
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||||
|
[assembly : AssemblyProduct("OdePlugin")]
|
||||||
|
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
||||||
|
[assembly : AssemblyTrademark("")]
|
||||||
|
[assembly : AssemblyCulture("")]
|
||||||
|
|
||||||
|
// This sets the default COM visibility of types in the assembly to invisible.
|
||||||
|
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||||
|
|
||||||
|
[assembly : ComVisible(false)]
|
||||||
|
|
||||||
|
// The assembly version has following format :
|
||||||
|
//
|
||||||
|
// Major.Minor.Build.Revision
|
||||||
|
//
|
||||||
|
// You can specify all values by your own or you can build default build and revision
|
||||||
|
// numbers with the '*' character (the default):
|
||||||
|
|
||||||
|
[assembly : AssemblyVersion("0.6.5.*")]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,630 @@
|
||||||
|
/*
|
||||||
|
* Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||||
|
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||||
|
* characteristics and Kinetic motion.
|
||||||
|
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||||
|
* (dynamics) and the associated settings. Old Linear and angular
|
||||||
|
* motors for dynamic motion have been replace with MoveLinear()
|
||||||
|
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||||
|
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||||
|
* switch between 'VEHICLE' parameter use and general dynamics
|
||||||
|
* settings use.
|
||||||
|
*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Ode.NET;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
public class ODEDynamics
|
||||||
|
{
|
||||||
|
public Vehicle Type
|
||||||
|
{
|
||||||
|
get { return m_type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Body
|
||||||
|
{
|
||||||
|
get { return m_body; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private int frcount = 0; // Used to limit dynamics debug output to
|
||||||
|
// every 100th frame
|
||||||
|
|
||||||
|
// private OdeScene m_parentScene = null;
|
||||||
|
private IntPtr m_body = IntPtr.Zero;
|
||||||
|
private IntPtr m_jointGroup = IntPtr.Zero;
|
||||||
|
private IntPtr m_aMotor = IntPtr.Zero;
|
||||||
|
|
||||||
|
|
||||||
|
// Vehicle properties
|
||||||
|
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||||
|
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||||
|
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||||
|
// HOVER_TERRAIN_ONLY
|
||||||
|
// HOVER_GLOBAL_HEIGHT
|
||||||
|
// NO_DEFLECTION_UP
|
||||||
|
// HOVER_WATER_ONLY
|
||||||
|
// HOVER_UP_ONLY
|
||||||
|
// LIMIT_MOTOR_UP
|
||||||
|
// LIMIT_ROLL_ONLY
|
||||||
|
|
||||||
|
// Linear properties
|
||||||
|
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||||
|
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
||||||
|
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||||
|
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||||
|
private float m_linearMotorDecayTimescale = 0;
|
||||||
|
private float m_linearMotorTimescale = 0;
|
||||||
|
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
// private bool m_LinearMotorSetLastFrame = false;
|
||||||
|
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||||
|
|
||||||
|
//Angular properties
|
||||||
|
private Vector3 m_angularMotorDirection = Vector3.Zero;
|
||||||
|
private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero;
|
||||||
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero;
|
||||||
|
private float m_angularMotorDecayTimescale = 0;
|
||||||
|
private float m_angularMotorTimescale = 0;
|
||||||
|
private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
|
||||||
|
|
||||||
|
//Deflection properties
|
||||||
|
// private float m_angularDeflectionEfficiency = 0;
|
||||||
|
// private float m_angularDeflectionTimescale = 0;
|
||||||
|
// private float m_linearDeflectionEfficiency = 0;
|
||||||
|
// private float m_linearDeflectionTimescale = 0;
|
||||||
|
|
||||||
|
//Banking properties
|
||||||
|
// private float m_bankingEfficiency = 0;
|
||||||
|
// private float m_bankingMix = 0;
|
||||||
|
// private float m_bankingTimescale = 0;
|
||||||
|
|
||||||
|
//Hover and Buoyancy properties
|
||||||
|
private float m_VhoverHeight = 0f;
|
||||||
|
private float m_VhoverEfficiency = 0f;
|
||||||
|
private float m_VhoverTimescale = 0f;
|
||||||
|
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||||
|
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
||||||
|
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||||
|
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||||
|
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||||
|
|
||||||
|
//Attractor properties
|
||||||
|
private float m_verticalAttractionEfficiency = 0;
|
||||||
|
private float m_verticalAttractionTimescale = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_MIX:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingMix = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BUOYANCY:
|
||||||
|
if (pValue < -1f) pValue = -1f;
|
||||||
|
if (pValue > 1f) pValue = 1f;
|
||||||
|
m_VehicleBuoyancy = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_EFFICIENCY:
|
||||||
|
if (pValue < 0f) pValue = 0f;
|
||||||
|
if (pValue > 1f) pValue = 1f;
|
||||||
|
m_VhoverEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_HEIGHT:
|
||||||
|
m_VhoverHeight = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_VhoverTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.0f) pValue = 0.0f;
|
||||||
|
if (pValue > 1.0f) pValue = 1.0f;
|
||||||
|
m_verticalAttractionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_verticalAttractionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// These are vector properties but the engine lets you use a single float value to
|
||||||
|
// set all of the components to the same value
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessFloatVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessVectorVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.REFERENCE_FRAME:
|
||||||
|
// m_referenceFrame = pValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessRotationVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessTypeChange(Vehicle pType)
|
||||||
|
{
|
||||||
|
Console.WriteLine("ProcessTypeChange to " + pType);
|
||||||
|
|
||||||
|
// Set Defaults For Type
|
||||||
|
m_type = pType;
|
||||||
|
switch (pType)
|
||||||
|
{
|
||||||
|
case Vehicle.TYPE_SLED:
|
||||||
|
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1000;
|
||||||
|
m_linearMotorDecayTimescale = 120;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1000;
|
||||||
|
m_angularMotorDecayTimescale = 120;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 1;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 1;
|
||||||
|
// m_linearDeflectionTimescale = 1;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 1000;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 10;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &=
|
||||||
|
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_CAR:
|
||||||
|
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1;
|
||||||
|
m_angularMotorDecayTimescale = 0.8f;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 0;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// // m_linearDeflectionEfficiency = 1;
|
||||||
|
// // m_linearDeflectionTimescale = 2;
|
||||||
|
// // m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 10;
|
||||||
|
m_verticalAttractionEfficiency = 1;
|
||||||
|
m_verticalAttractionTimescale = 10;
|
||||||
|
// m_bankingEfficiency = -0.2f;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BOAT:
|
||||||
|
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10,10,10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 2;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 0.5f;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 0.5f;
|
||||||
|
m_verticalAttractionTimescale = 5;
|
||||||
|
// m_bankingEfficiency = -0.3f;
|
||||||
|
// m_bankingMix = 0.8f;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_AIRPLANE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 2;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 2;
|
||||||
|
m_verticalAttractionEfficiency = 0.9f;
|
||||||
|
m_verticalAttractionTimescale = 2;
|
||||||
|
// m_bankingEfficiency = 1;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 2;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BALLOON:
|
||||||
|
m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 6;
|
||||||
|
m_angularMotorDecayTimescale = 10;
|
||||||
|
m_VhoverHeight = 5;
|
||||||
|
m_VhoverEfficiency = 0.8f;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0;
|
||||||
|
// m_linearDeflectionTimescale = 5;
|
||||||
|
// m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 1;
|
||||||
|
m_verticalAttractionTimescale = 1000;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 5;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}//end SetDefaultsForType
|
||||||
|
|
||||||
|
internal void Enable(IntPtr pBody, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy);
|
||||||
|
if (m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_body = pBody;
|
||||||
|
//KF: This used to set up the linear and angular joints
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Step(float pTimestep, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
frcount++; // used to limit debug comment output
|
||||||
|
if (frcount > 100)
|
||||||
|
frcount = 0;
|
||||||
|
|
||||||
|
MoveLinear(pTimestep, pParentScene);
|
||||||
|
MoveAngular(pTimestep);
|
||||||
|
}// end Step
|
||||||
|
|
||||||
|
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
|
||||||
|
{
|
||||||
|
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
|
||||||
|
// add drive to body
|
||||||
|
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
|
||||||
|
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
|
||||||
|
|
||||||
|
// This will work temporarily, but we really need to compare speed on an axis
|
||||||
|
// KF: Limit body velocity to applied velocity?
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||||
|
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
|
||||||
|
m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
|
||||||
|
m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
|
||||||
|
|
||||||
|
// decay applied velocity
|
||||||
|
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
|
||||||
|
//Console.WriteLine("decay: " + decayfraction);
|
||||||
|
m_linearMotorDirection -= m_linearMotorDirection * decayfraction;
|
||||||
|
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // requested is not significant
|
||||||
|
// if what remains of applied is small, zero it.
|
||||||
|
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// convert requested object velocity to world-referenced vector
|
||||||
|
m_dir = m_lastLinearVelocityVector;
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||||
|
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||||
|
|
||||||
|
// add Gravity andBuoyancy
|
||||||
|
// KF: So far I have found no good method to combine a script-requested
|
||||||
|
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
||||||
|
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||||
|
Vector3 grav = Vector3.Zero;
|
||||||
|
if(m_VehicleBuoyancy < 1.0f)
|
||||||
|
{
|
||||||
|
// There is some gravity, make a gravity force vector
|
||||||
|
// that is applied after object velocity.
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||||
|
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
|
||||||
|
// Preserve the current Z velocity
|
||||||
|
d.Vector3 vel_now = d.BodyGetLinearVel(Body);
|
||||||
|
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||||
|
} // else its 1.0, no gravity.
|
||||||
|
|
||||||
|
// Check if hovering
|
||||||
|
if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||||
|
{
|
||||||
|
// We should hover, get the target height
|
||||||
|
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||||
|
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = m_VhoverHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
|
||||||
|
{
|
||||||
|
// If body is aready heigher, use its height as target height
|
||||||
|
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||||
|
// m_VhoverTimescale = 0f; // time to acheive height
|
||||||
|
// pTimestep is time since last frame,in secs
|
||||||
|
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||||
|
//if(frcount == 0) Console.WriteLine("herr0=" + herr0);
|
||||||
|
// Replace Vertical speed with correction figure if significant
|
||||||
|
if(Math.Abs(herr0) > 0.01f )
|
||||||
|
{
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||||
|
// m_VhoverEfficiency is not yet implemented
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_dir.Z = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply velocity
|
||||||
|
d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
|
||||||
|
//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z);
|
||||||
|
// apply gravity force
|
||||||
|
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
|
||||||
|
//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z);
|
||||||
|
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||||
|
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||||
|
} // end MoveLinear()
|
||||||
|
|
||||||
|
private void MoveAngular(float pTimestep)
|
||||||
|
{
|
||||||
|
|
||||||
|
// m_angularMotorDirection is the latest value from the script, and is decayed here
|
||||||
|
// m_angularMotorDirectionLASTSET is the latest value from the script
|
||||||
|
// m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here
|
||||||
|
|
||||||
|
if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
// ramp up to new value
|
||||||
|
Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep);
|
||||||
|
m_lastAngularVelocityVector += (addAmount * 10f);
|
||||||
|
//if(frcount == 0) Console.WriteLine("add: " + addAmount);
|
||||||
|
|
||||||
|
// limit applied value to what was set by script
|
||||||
|
// This will work temporarily, but we really need to compare speed on an axis
|
||||||
|
if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X))
|
||||||
|
m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X;
|
||||||
|
if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y))
|
||||||
|
m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y;
|
||||||
|
if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z))
|
||||||
|
m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z;
|
||||||
|
|
||||||
|
// decay the requested value
|
||||||
|
Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep)));
|
||||||
|
//Console.WriteLine("decay: " + decayfraction);
|
||||||
|
m_angularMotorDirection -= m_angularMotorDirection * decayfraction;
|
||||||
|
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||||
|
}
|
||||||
|
// KF: m_lastAngularVelocityVector is rotational speed in rad/sec ?
|
||||||
|
|
||||||
|
// Vertical attractor section
|
||||||
|
|
||||||
|
// d.Mass objMass;
|
||||||
|
// d.BodyGetMass(Body, out objMass);
|
||||||
|
// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||||
|
float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||||
|
// get present body rotation
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||||
|
// make a vector pointing up
|
||||||
|
Vector3 verterr = Vector3.Zero;
|
||||||
|
verterr.Z = 1.0f;
|
||||||
|
// rotate it to Body Angle
|
||||||
|
verterr = verterr * rotq;
|
||||||
|
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||||
|
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||||
|
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||||
|
if (verterr.Z < 0.0f)
|
||||||
|
{
|
||||||
|
verterr.X = 2.0f - verterr.X;
|
||||||
|
verterr.Y = 2.0f - verterr.Y;
|
||||||
|
}
|
||||||
|
// Error is 0 (no error) to +/- 2 (max error)
|
||||||
|
// scale it by servo
|
||||||
|
verterr = verterr * servo;
|
||||||
|
|
||||||
|
// rotate to object frame
|
||||||
|
// verterr = verterr * rotq;
|
||||||
|
|
||||||
|
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||||
|
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||||
|
m_lastAngularVelocityVector.X += verterr.Y;
|
||||||
|
m_lastAngularVelocityVector.Y -= verterr.X;
|
||||||
|
/*
|
||||||
|
if(frcount == 0)
|
||||||
|
{
|
||||||
|
// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector);
|
||||||
|
Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}",
|
||||||
|
Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z);
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
|
||||||
|
m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount;
|
||||||
|
|
||||||
|
} //end MoveAngular
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,673 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||||
|
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||||
|
* characteristics and Kinetic motion.
|
||||||
|
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||||
|
* (dynamics) and the associated settings. Old Linear and angular
|
||||||
|
* motors for dynamic motion have been replace with MoveLinear()
|
||||||
|
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||||
|
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||||
|
* switch between 'VEHICLE' parameter use and general dynamics
|
||||||
|
* settings use.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||||
|
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||||
|
* characteristics and Kinetic motion.
|
||||||
|
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||||
|
* (dynamics) and the associated settings. Old Linear and angular
|
||||||
|
* motors for dynamic motion have been replace with MoveLinear()
|
||||||
|
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||||
|
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||||
|
* switch between 'VEHICLE' parameter use and general dynamics
|
||||||
|
* settings use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Ode.NET;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
public class ODEDynamics
|
||||||
|
{
|
||||||
|
public Vehicle Type
|
||||||
|
{
|
||||||
|
get { return m_type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Body
|
||||||
|
{
|
||||||
|
get { return m_body; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private int frcount = 0; // Used to limit dynamics debug output to
|
||||||
|
// every 100th frame
|
||||||
|
|
||||||
|
// private OdeScene m_parentScene = null;
|
||||||
|
private IntPtr m_body = IntPtr.Zero;
|
||||||
|
// private IntPtr m_jointGroup = IntPtr.Zero;
|
||||||
|
// private IntPtr m_aMotor = IntPtr.Zero;
|
||||||
|
|
||||||
|
|
||||||
|
// Vehicle properties
|
||||||
|
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||||
|
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||||
|
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||||
|
// HOVER_TERRAIN_ONLY
|
||||||
|
// HOVER_GLOBAL_HEIGHT
|
||||||
|
// NO_DEFLECTION_UP
|
||||||
|
// HOVER_WATER_ONLY
|
||||||
|
// HOVER_UP_ONLY
|
||||||
|
// LIMIT_MOTOR_UP
|
||||||
|
// LIMIT_ROLL_ONLY
|
||||||
|
|
||||||
|
// Linear properties
|
||||||
|
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||||
|
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
||||||
|
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||||
|
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||||
|
private float m_linearMotorDecayTimescale = 0;
|
||||||
|
private float m_linearMotorTimescale = 0;
|
||||||
|
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
// private bool m_LinearMotorSetLastFrame = false;
|
||||||
|
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||||
|
|
||||||
|
//Angular properties
|
||||||
|
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||||
|
private int m_angularMotorApply = 0; // application frame counter
|
||||||
|
private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
|
||||||
|
private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
|
||||||
|
private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
|
||||||
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||||
|
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||||
|
// private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body
|
||||||
|
|
||||||
|
//Deflection properties
|
||||||
|
// private float m_angularDeflectionEfficiency = 0;
|
||||||
|
// private float m_angularDeflectionTimescale = 0;
|
||||||
|
// private float m_linearDeflectionEfficiency = 0;
|
||||||
|
// private float m_linearDeflectionTimescale = 0;
|
||||||
|
|
||||||
|
//Banking properties
|
||||||
|
// private float m_bankingEfficiency = 0;
|
||||||
|
// private float m_bankingMix = 0;
|
||||||
|
// private float m_bankingTimescale = 0;
|
||||||
|
|
||||||
|
//Hover and Buoyancy properties
|
||||||
|
private float m_VhoverHeight = 0f;
|
||||||
|
// private float m_VhoverEfficiency = 0f;
|
||||||
|
private float m_VhoverTimescale = 0f;
|
||||||
|
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||||
|
private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle.
|
||||||
|
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||||
|
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||||
|
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||||
|
|
||||||
|
//Attractor properties
|
||||||
|
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||||
|
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_MIX:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingMix = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BUOYANCY:
|
||||||
|
if (pValue < -1f) pValue = -1f;
|
||||||
|
if (pValue > 1f) pValue = 1f;
|
||||||
|
m_VehicleBuoyancy = pValue;
|
||||||
|
break;
|
||||||
|
// case Vehicle.HOVER_EFFICIENCY:
|
||||||
|
// if (pValue < 0f) pValue = 0f;
|
||||||
|
// if (pValue > 1f) pValue = 1f;
|
||||||
|
// m_VhoverEfficiency = pValue;
|
||||||
|
// break;
|
||||||
|
case Vehicle.HOVER_HEIGHT:
|
||||||
|
m_VhoverHeight = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_VhoverTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable
|
||||||
|
if (pValue > 1.0f) pValue = 1.0f;
|
||||||
|
m_verticalAttractionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_verticalAttractionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// These are vector properties but the engine lets you use a single float value to
|
||||||
|
// set all of the components to the same value
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_angularMotorApply = 10;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessFloatVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
||||||
|
if(m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f;
|
||||||
|
if(m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f;
|
||||||
|
if(m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f;
|
||||||
|
if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f;
|
||||||
|
if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f;
|
||||||
|
if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f;
|
||||||
|
m_angularMotorApply = 10;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessVectorVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.REFERENCE_FRAME:
|
||||||
|
// m_referenceFrame = pValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessRotationVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessTypeChange(Vehicle pType)
|
||||||
|
{
|
||||||
|
// Set Defaults For Type
|
||||||
|
m_type = pType;
|
||||||
|
switch (pType)
|
||||||
|
{
|
||||||
|
case Vehicle.TYPE_SLED:
|
||||||
|
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1000;
|
||||||
|
m_linearMotorDecayTimescale = 120;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1000;
|
||||||
|
m_angularMotorDecayTimescale = 120;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 1;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 1;
|
||||||
|
// m_linearDeflectionTimescale = 1;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 1000;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 10;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &=
|
||||||
|
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_CAR:
|
||||||
|
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1;
|
||||||
|
m_angularMotorDecayTimescale = 0.8f;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 0;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// // m_linearDeflectionEfficiency = 1;
|
||||||
|
// // m_linearDeflectionTimescale = 2;
|
||||||
|
// // m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 10;
|
||||||
|
m_verticalAttractionEfficiency = 1f;
|
||||||
|
m_verticalAttractionTimescale = 10f;
|
||||||
|
// m_bankingEfficiency = -0.2f;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BOAT:
|
||||||
|
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10,10,10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 2;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 0.5f;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 0.5f;
|
||||||
|
m_verticalAttractionTimescale = 5f;
|
||||||
|
// m_bankingEfficiency = -0.3f;
|
||||||
|
// m_bankingMix = 0.8f;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_AIRPLANE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 2;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 2;
|
||||||
|
m_verticalAttractionEfficiency = 0.9f;
|
||||||
|
m_verticalAttractionTimescale = 2f;
|
||||||
|
// m_bankingEfficiency = 1;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 2;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BALLOON:
|
||||||
|
m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 6;
|
||||||
|
m_angularMotorDecayTimescale = 10;
|
||||||
|
m_VhoverHeight = 5;
|
||||||
|
// m_VhoverEfficiency = 0.8f;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0;
|
||||||
|
// m_linearDeflectionTimescale = 5;
|
||||||
|
// m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 1f;
|
||||||
|
m_verticalAttractionTimescale = 100f;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 5;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}//end SetDefaultsForType
|
||||||
|
|
||||||
|
internal void Enable(IntPtr pBody, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
if (m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_body = pBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Step(float pTimestep, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
frcount++; // used to limit debug comment output
|
||||||
|
if (frcount > 100)
|
||||||
|
frcount = 0;
|
||||||
|
|
||||||
|
MoveLinear(pTimestep, pParentScene);
|
||||||
|
MoveAngular(pTimestep);
|
||||||
|
}// end Step
|
||||||
|
|
||||||
|
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
|
||||||
|
{
|
||||||
|
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
|
||||||
|
// add drive to body
|
||||||
|
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
|
||||||
|
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
|
||||||
|
|
||||||
|
// This will work temporarily, but we really need to compare speed on an axis
|
||||||
|
// KF: Limit body velocity to applied velocity?
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||||
|
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
|
||||||
|
m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
|
||||||
|
m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
|
||||||
|
|
||||||
|
// decay applied velocity
|
||||||
|
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
|
||||||
|
//Console.WriteLine("decay: " + decayfraction);
|
||||||
|
m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
|
||||||
|
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // requested is not significant
|
||||||
|
// if what remains of applied is small, zero it.
|
||||||
|
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// convert requested object velocity to world-referenced vector
|
||||||
|
m_dir = m_lastLinearVelocityVector;
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||||
|
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||||
|
|
||||||
|
// add Gravity and Buoyancy
|
||||||
|
// KF: So far I have found no good method to combine a script-requested
|
||||||
|
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
||||||
|
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||||
|
Vector3 grav = Vector3.Zero;
|
||||||
|
if(m_VehicleBuoyancy < 1.0f)
|
||||||
|
{
|
||||||
|
// There is some gravity, make a gravity force vector
|
||||||
|
// that is applied after object velocity.
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||||
|
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
|
||||||
|
// Preserve the current Z velocity
|
||||||
|
d.Vector3 vel_now = d.BodyGetLinearVel(Body);
|
||||||
|
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||||
|
} // else its 1.0, no gravity.
|
||||||
|
|
||||||
|
// Check if hovering
|
||||||
|
if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||||
|
{
|
||||||
|
// We should hover, get the target height
|
||||||
|
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||||
|
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = m_VhoverHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
|
||||||
|
{
|
||||||
|
// If body is aready heigher, use its height as target height
|
||||||
|
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||||
|
// m_VhoverTimescale = 0f; // time to acheive height
|
||||||
|
// pTimestep is time since last frame,in secs
|
||||||
|
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||||
|
// Replace Vertical speed with correction figure if significant
|
||||||
|
if(Math.Abs(herr0) > 0.01f )
|
||||||
|
{
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||||
|
//KF: m_VhoverEfficiency is not yet implemented
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_dir.Z = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply velocity
|
||||||
|
d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
|
||||||
|
// apply gravity force
|
||||||
|
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
|
||||||
|
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||||
|
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||||
|
} // end MoveLinear()
|
||||||
|
|
||||||
|
private void MoveAngular(float pTimestep)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||||
|
private int m_angularMotorApply = 0; // application frame counter
|
||||||
|
private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down)
|
||||||
|
private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
|
||||||
|
private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
|
||||||
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||||
|
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||||
|
*/
|
||||||
|
//if(frcount == 0) Console.WriteLine("MoveAngular ");
|
||||||
|
|
||||||
|
// Get what the body is doing, this includes 'external' influences
|
||||||
|
d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
|
||||||
|
// Vector3 angularVelocity = Vector3.Zero;
|
||||||
|
|
||||||
|
if (m_angularMotorApply > 0)
|
||||||
|
{
|
||||||
|
// ramp up to new value
|
||||||
|
// current velocity += error / ( time to get there / step interval )
|
||||||
|
// requested speed - last motor speed
|
||||||
|
m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
|
||||||
|
m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
|
||||||
|
m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
|
||||||
|
|
||||||
|
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
|
||||||
|
// velocity may still be acheived.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no motor recently applied, keep the body velocity
|
||||||
|
/* m_angularMotorVelocity.X = angularVelocity.X;
|
||||||
|
m_angularMotorVelocity.Y = angularVelocity.Y;
|
||||||
|
m_angularMotorVelocity.Z = angularVelocity.Z; */
|
||||||
|
|
||||||
|
// and decay the velocity
|
||||||
|
m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
|
||||||
|
} // end motor section
|
||||||
|
|
||||||
|
|
||||||
|
// Vertical attractor section
|
||||||
|
Vector3 vertattr = Vector3.Zero;
|
||||||
|
|
||||||
|
if(m_verticalAttractionTimescale < 300)
|
||||||
|
{
|
||||||
|
float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
|
||||||
|
// get present body rotation
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||||
|
// make a vector pointing up
|
||||||
|
Vector3 verterr = Vector3.Zero;
|
||||||
|
verterr.Z = 1.0f;
|
||||||
|
// rotate it to Body Angle
|
||||||
|
verterr = verterr * rotq;
|
||||||
|
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||||
|
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||||
|
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||||
|
if (verterr.Z < 0.0f)
|
||||||
|
{
|
||||||
|
verterr.X = 2.0f - verterr.X;
|
||||||
|
verterr.Y = 2.0f - verterr.Y;
|
||||||
|
}
|
||||||
|
// Error is 0 (no error) to +/- 2 (max error)
|
||||||
|
// scale it by VAservo
|
||||||
|
verterr = verterr * VAservo;
|
||||||
|
//if(frcount == 0) Console.WriteLine("VAerr=" + verterr);
|
||||||
|
|
||||||
|
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||||
|
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||||
|
vertattr.X = verterr.Y;
|
||||||
|
vertattr.Y = - verterr.X;
|
||||||
|
vertattr.Z = 0f;
|
||||||
|
|
||||||
|
// scaling appears better usingsquare-law
|
||||||
|
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||||
|
vertattr.X += bounce * angularVelocity.X;
|
||||||
|
vertattr.Y += bounce * angularVelocity.Y;
|
||||||
|
|
||||||
|
} // else vertical attractor is off
|
||||||
|
|
||||||
|
// m_lastVertAttractor = vertattr;
|
||||||
|
|
||||||
|
// Bank section tba
|
||||||
|
// Deflection section tba
|
||||||
|
|
||||||
|
// Sum velocities
|
||||||
|
m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection
|
||||||
|
|
||||||
|
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
|
||||||
|
m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
|
||||||
|
|
||||||
|
// Apply to the body
|
||||||
|
d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z);
|
||||||
|
|
||||||
|
} //end MoveAngular
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,375 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
using Ode.NET;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Processes raycast requests as ODE is in a state to be able to do them.
|
||||||
|
/// This ensures that it's thread safe and there will be no conflicts.
|
||||||
|
/// Requests get returned by a different thread then they were requested by.
|
||||||
|
/// </summary>
|
||||||
|
public class ODERayCastRequestManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pending Raycast Requests
|
||||||
|
/// </summary>
|
||||||
|
protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scene that created this object.
|
||||||
|
/// </summary>
|
||||||
|
private OdeScene m_scene;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ODE contact array to be filled by the collision testing
|
||||||
|
/// </summary>
|
||||||
|
d.ContactGeom[] contacts = new d.ContactGeom[5];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ODE near callback delegate
|
||||||
|
/// </summary>
|
||||||
|
private d.NearCallback nearCallback;
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private List<ContactResult> m_contactResults = new List<ContactResult>();
|
||||||
|
|
||||||
|
|
||||||
|
public ODERayCastRequestManager(OdeScene pScene)
|
||||||
|
{
|
||||||
|
m_scene = pScene;
|
||||||
|
nearCallback = near;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queues a raycast
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position">Origin of Ray</param>
|
||||||
|
/// <param name="direction">Ray normal</param>
|
||||||
|
/// <param name="length">Ray length</param>
|
||||||
|
/// <param name="retMethod">Return method to send the results</param>
|
||||||
|
public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
||||||
|
{
|
||||||
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
ODERayCastRequest req = new ODERayCastRequest();
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = length;
|
||||||
|
req.Normal = direction;
|
||||||
|
req.Origin = position;
|
||||||
|
|
||||||
|
m_PendingRequests.Add(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process all queued raycast requests
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Time in MS the raycasts took to process.</returns>
|
||||||
|
public int ProcessQueuedRequests()
|
||||||
|
{
|
||||||
|
int time = System.Environment.TickCount;
|
||||||
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
if (m_PendingRequests.Count > 0)
|
||||||
|
{
|
||||||
|
ODERayCastRequest[] reqs = m_PendingRequests.ToArray();
|
||||||
|
for (int i = 0; i < reqs.Length; i++)
|
||||||
|
{
|
||||||
|
if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
|
||||||
|
RayCast(reqs[i]); // if there isn't anyone to send results
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
foreach (ODERayCastRequest req in m_PendingRequests)
|
||||||
|
{
|
||||||
|
if (req.callbackMethod != null) // quick optimization here, don't raycast
|
||||||
|
RayCast(req); // if there isn't anyone to send results to
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
m_PendingRequests.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (m_contactResults)
|
||||||
|
m_contactResults.Clear();
|
||||||
|
|
||||||
|
return System.Environment.TickCount - time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method that actually initiates the raycast
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="req"></param>
|
||||||
|
private void RayCast(ODERayCastRequest req)
|
||||||
|
{
|
||||||
|
// Create the ray
|
||||||
|
IntPtr ray = d.CreateRay(m_scene.space, req.length);
|
||||||
|
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
|
||||||
|
|
||||||
|
// Collide test
|
||||||
|
d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
|
||||||
|
|
||||||
|
// Remove Ray
|
||||||
|
d.GeomDestroy(ray);
|
||||||
|
|
||||||
|
|
||||||
|
// Define default results
|
||||||
|
bool hitYN = false;
|
||||||
|
uint hitConsumerID = 0;
|
||||||
|
float distance = 999999999999f;
|
||||||
|
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
|
||||||
|
Vector3 snormal = Vector3.Zero;
|
||||||
|
|
||||||
|
// Find closest contact and object.
|
||||||
|
lock (m_contactResults)
|
||||||
|
{
|
||||||
|
foreach (ContactResult cResult in m_contactResults)
|
||||||
|
{
|
||||||
|
if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
|
||||||
|
{
|
||||||
|
closestcontact = cResult.Pos;
|
||||||
|
hitConsumerID = cResult.ConsumerID;
|
||||||
|
distance = cResult.Depth;
|
||||||
|
hitYN = true;
|
||||||
|
snormal = cResult.Normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_contactResults.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return results
|
||||||
|
if (req.callbackMethod != null)
|
||||||
|
req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 = ((OdePrim)p1).m_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 = ((OdePrim)p2).m_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dereference the creator scene so that it can be garbage collected if needed.
|
||||||
|
/// </summary>
|
||||||
|
internal void Dispose()
|
||||||
|
{
|
||||||
|
m_scene = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ODERayCastRequest
|
||||||
|
{
|
||||||
|
public Vector3 Origin;
|
||||||
|
public Vector3 Normal;
|
||||||
|
public float length;
|
||||||
|
public RaycastCallback callbackMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ContactResult
|
||||||
|
{
|
||||||
|
public Vector3 Pos;
|
||||||
|
public float Depth;
|
||||||
|
public uint ConsumerID;
|
||||||
|
public Vector3 Normal;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Ode.NET;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
using OpenSim.Region.Physics.OdePlugin;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
class OdePhysicsJoint : PhysicsJoint
|
||||||
|
{
|
||||||
|
public override bool IsInPhysicsEngine
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (jointID != IntPtr.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public IntPtr jointID;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
using log4net;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ODETestClass
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private OdePlugin cbt;
|
||||||
|
private PhysicsScene ps;
|
||||||
|
private IMeshingPlugin imp;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
// Loading ODEPlugin
|
||||||
|
cbt = new OdePlugin();
|
||||||
|
// Loading Zero Mesher
|
||||||
|
imp = new ZeroMesherPlugin();
|
||||||
|
// Getting Physics Scene
|
||||||
|
ps = cbt.GetScene("test");
|
||||||
|
// Initializing Physics Scene.
|
||||||
|
ps.Initialise(imp.GetMesher(),null);
|
||||||
|
float[] _heightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize];
|
||||||
|
for (int i = 0; i < ((int)Constants.RegionSize * (int)Constants.RegionSize); i++)
|
||||||
|
{
|
||||||
|
_heightmap[i] = 21f;
|
||||||
|
}
|
||||||
|
ps.SetTerrain(_heightmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void Terminate()
|
||||||
|
{
|
||||||
|
ps.DeleteTerrain();
|
||||||
|
ps.Dispose();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateAndDropPhysicalCube()
|
||||||
|
{
|
||||||
|
PrimitiveBaseShape newcube = PrimitiveBaseShape.CreateBox();
|
||||||
|
Vector3 position = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 128f);
|
||||||
|
Vector3 size = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
Quaternion rot = Quaternion.Identity;
|
||||||
|
PhysicsActor prim = ps.AddPrimShape("CoolShape", newcube, position, size, rot, true);
|
||||||
|
OdePrim oprim = (OdePrim)prim;
|
||||||
|
OdeScene pscene = (OdeScene) ps;
|
||||||
|
|
||||||
|
Assert.That(oprim.m_taintadd);
|
||||||
|
|
||||||
|
prim.LocalID = 5;
|
||||||
|
|
||||||
|
for (int i = 0; i < 58; i++)
|
||||||
|
{
|
||||||
|
ps.Simulate(0.133f);
|
||||||
|
|
||||||
|
Assert.That(oprim.prim_geom != (IntPtr)0);
|
||||||
|
|
||||||
|
Assert.That(oprim.m_targetSpace != (IntPtr)0);
|
||||||
|
|
||||||
|
//Assert.That(oprim.m_targetSpace == pscene.space);
|
||||||
|
m_log.Info("TargetSpace: " + oprim.m_targetSpace + " - SceneMainSpace: " + pscene.space);
|
||||||
|
|
||||||
|
Assert.That(!oprim.m_taintadd);
|
||||||
|
m_log.Info("Prim Position (" + oprim.m_localID + "): " + prim.Position.ToString());
|
||||||
|
|
||||||
|
// Make sure we're above the ground
|
||||||
|
//Assert.That(prim.Position.Z > 20f);
|
||||||
|
//m_log.Info("PrimCollisionScore (" + oprim.m_localID + "): " + oprim.m_collisionscore);
|
||||||
|
|
||||||
|
// Make sure we've got a Body
|
||||||
|
Assert.That(oprim.Body != (IntPtr)0);
|
||||||
|
//m_log.Info(
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we're not somewhere above the ground
|
||||||
|
Assert.That(prim.Position.Z < 21.5f);
|
||||||
|
|
||||||
|
ps.RemovePrim(prim);
|
||||||
|
Assert.That(oprim.m_taintremove);
|
||||||
|
ps.Simulate(0.133f);
|
||||||
|
Assert.That(oprim.Body == (IntPtr)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright ODE
|
||||||
|
* Ode.NET - .NET bindings for ODE
|
||||||
|
* Jason Perkins (starkos@industriousone.com)
|
||||||
|
* Licensed under the New BSD
|
||||||
|
* Part of the OpenDynamicsEngine
|
||||||
|
Open Dynamics Engine
|
||||||
|
Copyright (c) 2001-2007, Russell L. Smith.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
Neither the names of ODE's copyright owner nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Ode.NET;
|
||||||
|
|
||||||
|
namespace Drawstuff.NET
|
||||||
|
{
|
||||||
|
#if dDOUBLE
|
||||||
|
using dReal = System.Double;
|
||||||
|
#else
|
||||||
|
using dReal = System.Single;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public static class ds
|
||||||
|
{
|
||||||
|
public const int VERSION = 2;
|
||||||
|
|
||||||
|
public enum Texture
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Wood
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
public delegate void CallbackFunction(int arg);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct Functions
|
||||||
|
{
|
||||||
|
public int version;
|
||||||
|
public CallbackFunction start;
|
||||||
|
public CallbackFunction step;
|
||||||
|
public CallbackFunction command;
|
||||||
|
public CallbackFunction stop;
|
||||||
|
public string path_to_textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsDrawBox")]
|
||||||
|
public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsDrawCapsule")]
|
||||||
|
public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsDrawConvex")]
|
||||||
|
public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSetColor")]
|
||||||
|
public static extern void SetColor(float red, float green, float blue);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSetTexture")]
|
||||||
|
public static extern void SetTexture(Texture texture);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSetViewpoint")]
|
||||||
|
public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSimulationLoop")]
|
||||||
|
public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1197,25 +1197,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public override PIDHoverType PIDHoverType { set { return; } }
|
public override PIDHoverType PIDHoverType { set { return; } }
|
||||||
public override float PIDHoverTau { set { return; } }
|
public override float PIDHoverTau { set { return; } }
|
||||||
|
|
||||||
public override Quaternion APIDTarget
|
public override Quaternion APIDTarget{ set { return; } }
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool APIDActive
|
public override bool APIDActive{ set { return; } }
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override float APIDStrength
|
public override float APIDStrength{ set { return; } }
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override float APIDDamping
|
public override float APIDDamping{ set { return; } }
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SubscribeEvents(int ms)
|
public override void SubscribeEvents(int ms)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,19 +23,6 @@
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
|
||||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
|
||||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
|
||||||
* characteristics and Kinetic motion.
|
|
||||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
|
||||||
* (dynamics) and the associated settings. Old Linear and angular
|
|
||||||
* motors for dynamic motion have been replace with MoveLinear()
|
|
||||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
|
||||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
|
||||||
* switch between 'VEHICLE' parameter use and general dynamics
|
|
||||||
* settings use.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
@ -133,7 +120,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// private float m_VhoverEfficiency = 0f;
|
// private float m_VhoverEfficiency = 0f;
|
||||||
private float m_VhoverTimescale = 0f;
|
private float m_VhoverTimescale = 0f;
|
||||||
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||||
private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle.
|
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
||||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||||
|
@ -492,7 +479,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||||
m_dir *= rotq; // apply obj rotation to velocity vector
|
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||||
|
|
||||||
// add Gravity and Buoyancy
|
// add Gravity andBuoyancy
|
||||||
// KF: So far I have found no good method to combine a script-requested
|
// KF: So far I have found no good method to combine a script-requested
|
||||||
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
||||||
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||||
|
@ -574,7 +561,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||||
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||||
*/
|
*/
|
||||||
//if(frcount == 0) Console.WriteLine("MoveAngular ");
|
|
||||||
|
|
||||||
// Get what the body is doing, this includes 'external' influences
|
// Get what the body is doing, this includes 'external' influences
|
||||||
d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
|
d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
|
||||||
|
@ -650,7 +636,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// Deflection section tba
|
// Deflection section tba
|
||||||
|
|
||||||
// Sum velocities
|
// Sum velocities
|
||||||
m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection
|
m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection
|
||||||
|
|
||||||
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,18 +21,6 @@
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
|
|
||||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
|
||||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
|
||||||
* characteristics and Kinetic motion.
|
|
||||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
|
||||||
* (dynamics) and the associated settings. Old Linear and angular
|
|
||||||
* motors for dynamic motion have been replace with MoveLinear()
|
|
||||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
|
||||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
|
||||||
* switch between 'VEHICLE' parameter use and general dynamics
|
|
||||||
* settings use.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -93,12 +81,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private float m_PIDTau;
|
private float m_PIDTau;
|
||||||
private float PID_D = 35f;
|
private float PID_D = 35f;
|
||||||
private float PID_G = 25f;
|
private float PID_G = 25f;
|
||||||
private bool m_usePID = false;
|
private bool m_usePID;
|
||||||
|
|
||||||
private Quaternion m_APIDTarget = new Quaternion();
|
|
||||||
private float m_APIDStrength = 0.5f;
|
|
||||||
private float m_APIDDamping = 0.5f;
|
|
||||||
private bool m_useAPID = false;
|
|
||||||
|
|
||||||
// KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
|
// KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
|
||||||
// and are for non-VEHICLES only.
|
// and are for non-VEHICLES only.
|
||||||
|
@ -200,9 +183,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
internal int m_material = (int)Material.Wood;
|
internal int m_material = (int)Material.Wood;
|
||||||
|
|
||||||
private int frcount = 0; // Used to limit dynamics debug output to
|
|
||||||
|
|
||||||
|
|
||||||
public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
|
public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
|
||||||
Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
|
Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
|
||||||
{
|
{
|
||||||
|
@ -1581,14 +1561,9 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
float fy = 0;
|
float fy = 0;
|
||||||
float fz = 0;
|
float fz = 0;
|
||||||
|
|
||||||
frcount++; // used to limit debug comment output
|
|
||||||
if (frcount > 100)
|
|
||||||
frcount = 0;
|
|
||||||
|
|
||||||
if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
|
if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
|
||||||
{
|
{
|
||||||
//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type +
|
|
||||||
// " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID);
|
|
||||||
if (m_vehicle.Type != Vehicle.TYPE_NONE)
|
if (m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||||
{
|
{
|
||||||
// 'VEHICLES' are dealt with in ODEDynamics.cs
|
// 'VEHICLES' are dealt with in ODEDynamics.cs
|
||||||
|
@ -1596,6 +1571,7 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//Console.WriteLine("Move " + m_primName);
|
||||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
|
||||||
// NON-'VEHICLES' are dealt with here
|
// NON-'VEHICLES' are dealt with here
|
||||||
if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
|
if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
|
||||||
|
@ -1617,18 +1593,21 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
//m_log.Info(m_collisionFlags.ToString());
|
//m_log.Info(m_collisionFlags.ToString());
|
||||||
|
|
||||||
|
|
||||||
//KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle.
|
//KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
|
||||||
|
// would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ??
|
||||||
// m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
|
// m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
|
||||||
// NB Prims in ODE are no subject to global gravity
|
// gravityz multiplier = 1 - m_buoyancy
|
||||||
fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass
|
fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass;
|
||||||
|
|
||||||
if (m_usePID)
|
if (m_usePID)
|
||||||
{
|
{
|
||||||
//if(frcount == 0) Console.WriteLine("PID " + m_primName);
|
//Console.WriteLine("PID " + m_primName);
|
||||||
// KF - this is for object MoveToTarget.
|
// KF - this is for object move? eg. llSetPos() ?
|
||||||
|
|
||||||
//if (!d.BodyIsEnabled(Body))
|
//if (!d.BodyIsEnabled(Body))
|
||||||
//d.BodySetForce(Body, 0f, 0f, 0f);
|
//d.BodySetForce(Body, 0f, 0f, 0f);
|
||||||
|
// If we're using the PID controller, then we have no gravity
|
||||||
|
//fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply...
|
||||||
|
fz = 0f;
|
||||||
|
|
||||||
// no lock; for now it's only called from within Simulate()
|
// no lock; for now it's only called from within Simulate()
|
||||||
|
|
||||||
|
@ -1763,7 +1742,7 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
|
d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
|
||||||
d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
|
d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
|
||||||
d.BodyAddForce(Body, 0, 0, fz);
|
d.BodyAddForce(Body, 0, 0, fz);
|
||||||
//KF this prevents furthur motions return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1772,45 +1751,7 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
// We're flying and colliding with something
|
// We're flying and colliding with something
|
||||||
fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
|
fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
|
||||||
}
|
}
|
||||||
} // end m_useHoverPID && !m_usePID
|
}
|
||||||
|
|
||||||
if (m_useAPID)
|
|
||||||
{
|
|
||||||
// RotLookAt, apparently overrides all other rotation sources. Inputs:
|
|
||||||
// Quaternion m_APIDTarget
|
|
||||||
// float m_APIDStrength // From SL experiments, this is the time to get there
|
|
||||||
// float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly
|
|
||||||
// Also in SL the mass of the object has no effect on time to get there.
|
|
||||||
// Factors:
|
|
||||||
//if(frcount == 0) Console.WriteLine("APID ");
|
|
||||||
// get present body rotation
|
|
||||||
float limit = 1.0f;
|
|
||||||
float scaler = 50f; // adjusts damping time
|
|
||||||
float RLAservo = 0f;
|
|
||||||
|
|
||||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
|
||||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
|
||||||
Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget;
|
|
||||||
float diff_angle;
|
|
||||||
Vector3 diff_axis;
|
|
||||||
rot_diff.GetAxisAngle(out diff_axis, out diff_angle);
|
|
||||||
diff_axis.Normalize();
|
|
||||||
if(diff_angle > 0.01f) // diff_angle is always +ve
|
|
||||||
{
|
|
||||||
// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z);
|
|
||||||
Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z);
|
|
||||||
rotforce = rotforce * rotq;
|
|
||||||
if(diff_angle > limit) diff_angle = limit; // cap the rotate rate
|
|
||||||
// RLAservo = timestep / m_APIDStrength * m_mass * scaler;
|
|
||||||
// rotforce = rotforce * RLAservo * diff_angle ;
|
|
||||||
// d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z);
|
|
||||||
RLAservo = timestep / m_APIDStrength * scaler;
|
|
||||||
rotforce = rotforce * RLAservo * diff_angle ;
|
|
||||||
d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z);
|
|
||||||
//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo);
|
|
||||||
}
|
|
||||||
//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle);
|
|
||||||
} // end m_useAPID
|
|
||||||
|
|
||||||
fx *= m_mass;
|
fx *= m_mass;
|
||||||
fy *= m_mass;
|
fy *= m_mass;
|
||||||
|
@ -2682,10 +2623,6 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
l_orientation.Z = ori.Z;
|
l_orientation.Z = ori.Z;
|
||||||
l_orientation.W = ori.W;
|
l_orientation.W = ori.W;
|
||||||
|
|
||||||
// if(l_position.Y != m_lastposition.Y){
|
|
||||||
// Console.WriteLine("UP&V {0} {1}", m_primName, l_position);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
|
if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
|
||||||
{
|
{
|
||||||
//base.RaiseOutOfBounds(l_position);
|
//base.RaiseOutOfBounds(l_position);
|
||||||
|
|
30
prebuild.xml
30
prebuild.xml
|
@ -543,6 +543,36 @@
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
|
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ChOdePlugin" path="OpenSim/Region/Physics/ChOdePlugin" type="Library">
|
||||||
|
<Configuration name="Debug">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../../bin/Physics/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration name="Release">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../../bin/Physics/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
|
||||||
|
<ReferencePath>../../../../bin/</ReferencePath>
|
||||||
|
<Reference name="System"/>
|
||||||
|
<Reference name="System.Core"/>
|
||||||
|
<Reference name="OpenMetaverseTypes.dll"/>
|
||||||
|
<Reference name="Nini.dll" />
|
||||||
|
<Reference name="OpenSim.Framework"/>
|
||||||
|
<Reference name="OpenSim.Framework.Console"/>
|
||||||
|
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||||
|
<Reference name="Ode.NET.dll" />
|
||||||
|
<Reference name="log4net.dll"/>
|
||||||
|
|
||||||
|
<Files>
|
||||||
|
<Match pattern="*.cs" recurse="true">
|
||||||
|
<Exclude name="Tests" pattern="Tests"/>
|
||||||
|
</Match>
|
||||||
|
</Files>
|
||||||
|
</Project>
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletXPlugin" path="OpenSim/Region/Physics/BulletXPlugin" type="Library">
|
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletXPlugin" path="OpenSim/Region/Physics/BulletXPlugin" type="Library">
|
||||||
<Configuration name="Debug">
|
<Configuration name="Debug">
|
||||||
<Options>
|
<Options>
|
||||||
|
|
Loading…
Reference in New Issue