Merge branch 'ubitwork'
Conflicts: OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs OpenSim/Region/Physics/ChOdePlugin/OdePlugin.csavinationmerge
commit
96409cc2ee
|
@ -417,7 +417,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
so.AttachedAvatar = UUID.Zero;
|
||||
rootPart.SetParentLocalId(0);
|
||||
so.ClearPartAttachmentData();
|
||||
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive);
|
||||
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
|
||||
so.HasGroupChanged = true;
|
||||
rootPart.Rezzed = DateTime.Now;
|
||||
rootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
|
|
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* 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 OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using System.Xml;
|
||||
using OpenSim.Framework.Serialization;
|
||||
using OpenSim.Framework.Serialization.External;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
public class SOPVehicle
|
||||
{
|
||||
public VehicleData vd;
|
||||
|
||||
public Vehicle Type
|
||||
{
|
||||
get { return vd.m_type; }
|
||||
}
|
||||
|
||||
public SOPVehicle()
|
||||
{
|
||||
vd = new VehicleData();
|
||||
ProcessTypeChange(Vehicle.TYPE_NONE); // is needed?
|
||||
}
|
||||
|
||||
public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
float len;
|
||||
float timestep = 0.01f;
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_angularDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_angularDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
vd.m_angularMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_angularMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_EFFICIENCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_bankingEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_MIX:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_bankingMix = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_bankingTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BUOYANCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_VehicleBuoyancy = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_VhoverEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_HEIGHT:
|
||||
vd.m_VhoverHeight = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_VhoverTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_linearDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_linearDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||
// if (pValue < timestep) pValue = timestep;
|
||||
// try to make impulses to work a bit better
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
vd.m_linearMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_linearMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_verticalAttractionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.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:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
vd.m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
len = vd.m_angularMotorDirection.Length();
|
||||
if (len > 12.566f)
|
||||
vd.m_angularMotorDirection *= (12.566f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
vd.m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
len = vd.m_linearMotorDirection.Length();
|
||||
if (len > 30.0f)
|
||||
vd.m_linearMotorDirection *= (30.0f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
vd.m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
len = vd.m_linearMotorOffset.Length();
|
||||
if (len > 100.0f)
|
||||
vd.m_linearMotorOffset *= (100.0f / len);
|
||||
break;
|
||||
}
|
||||
}//end ProcessFloatVehicleParam
|
||||
|
||||
public void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||
{
|
||||
float len;
|
||||
float timestep = 0.01f;
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
if (pValue.Y < timestep) pValue.Y = timestep;
|
||||
if (pValue.Z < timestep) pValue.Z = timestep;
|
||||
|
||||
vd.m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
vd.m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
||||
len = vd.m_angularMotorDirection.Length();
|
||||
if (len > 12.566f)
|
||||
vd.m_angularMotorDirection *= (12.566f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
if (pValue.Y < timestep) pValue.Y = timestep;
|
||||
if (pValue.Z < timestep) pValue.Z = timestep;
|
||||
vd.m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
vd.m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
len = vd.m_linearMotorDirection.Length();
|
||||
if (len > 30.0f)
|
||||
vd.m_linearMotorDirection *= (30.0f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
vd.m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
len = vd.m_linearMotorOffset.Length();
|
||||
if (len > 100.0f)
|
||||
vd.m_linearMotorOffset *= (100.0f / len);
|
||||
break;
|
||||
}
|
||||
}//end ProcessVectorVehicleParam
|
||||
|
||||
public void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.REFERENCE_FRAME:
|
||||
vd.m_referenceFrame = Quaternion.Inverse(pValue);
|
||||
break;
|
||||
}
|
||||
}//end ProcessRotationVehicleParam
|
||||
|
||||
public void ProcessVehicleFlags(int pParam, bool remove)
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
vd.m_flags &= ~((VehicleFlag)pParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
vd.m_flags |= (VehicleFlag)pParam;
|
||||
}
|
||||
}//end ProcessVehicleFlags
|
||||
|
||||
public void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
vd.m_linearMotorDirection = Vector3.Zero;
|
||||
vd.m_angularMotorDirection = Vector3.Zero;
|
||||
vd.m_linearMotorOffset = Vector3.Zero;
|
||||
vd.m_referenceFrame = Quaternion.Identity;
|
||||
|
||||
// Set Defaults For Type
|
||||
vd.m_type = pType;
|
||||
switch (pType)
|
||||
{
|
||||
case Vehicle.TYPE_NONE:
|
||||
vd.m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_linearMotorTimescale = 1000;
|
||||
vd.m_linearMotorDecayTimescale = 120;
|
||||
vd.m_angularMotorTimescale = 1000;
|
||||
vd.m_angularMotorDecayTimescale = 1000;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 1;
|
||||
vd.m_VhoverTimescale = 1000;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 0;
|
||||
vd.m_linearDeflectionTimescale = 1000;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 1000;
|
||||
vd.m_bankingEfficiency = 0;
|
||||
vd.m_bankingMix = 1;
|
||||
vd.m_bankingTimescale = 1000;
|
||||
vd.m_verticalAttractionEfficiency = 0;
|
||||
vd.m_verticalAttractionTimescale = 1000;
|
||||
|
||||
vd.m_flags = (VehicleFlag)0;
|
||||
break;
|
||||
|
||||
case Vehicle.TYPE_SLED:
|
||||
vd.m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_linearMotorTimescale = 1000;
|
||||
vd.m_linearMotorDecayTimescale = 120;
|
||||
vd.m_angularMotorTimescale = 1000;
|
||||
vd.m_angularMotorDecayTimescale = 120;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 1;
|
||||
vd.m_VhoverTimescale = 10;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 1;
|
||||
vd.m_linearDeflectionTimescale = 1;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 1000;
|
||||
vd.m_bankingEfficiency = 0;
|
||||
vd.m_bankingMix = 1;
|
||||
vd.m_bankingTimescale = 10;
|
||||
vd.m_flags &=
|
||||
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_CAR:
|
||||
vd.m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_linearMotorTimescale = 1;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 1;
|
||||
vd.m_angularMotorDecayTimescale = 0.8f;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 0;
|
||||
vd.m_VhoverTimescale = 1000;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 1;
|
||||
vd.m_linearDeflectionTimescale = 2;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 10;
|
||||
vd.m_verticalAttractionEfficiency = 1f;
|
||||
vd.m_verticalAttractionTimescale = 10f;
|
||||
vd.m_bankingEfficiency = -0.2f;
|
||||
vd.m_bankingMix = 1;
|
||||
vd.m_bankingTimescale = 1;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BOAT:
|
||||
vd.m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||
vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
vd.m_linearMotorTimescale = 5;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 4;
|
||||
vd.m_angularMotorDecayTimescale = 4;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 0.5f;
|
||||
vd.m_VhoverTimescale = 2;
|
||||
vd.m_VehicleBuoyancy = 1;
|
||||
vd.m_linearDeflectionEfficiency = 0.5f;
|
||||
vd.m_linearDeflectionTimescale = 3;
|
||||
vd.m_angularDeflectionEfficiency = 0.5f;
|
||||
vd.m_angularDeflectionTimescale = 5;
|
||||
vd.m_verticalAttractionEfficiency = 0.5f;
|
||||
vd.m_verticalAttractionTimescale = 5f;
|
||||
vd.m_bankingEfficiency = -0.3f;
|
||||
vd.m_bankingMix = 0.8f;
|
||||
vd.m_bankingTimescale = 1;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP |
|
||||
VehicleFlag.HOVER_WATER_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_AIRPLANE:
|
||||
vd.m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||
vd.m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||
vd.m_linearMotorTimescale = 2;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 4;
|
||||
vd.m_angularMotorDecayTimescale = 8;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 0.5f;
|
||||
vd.m_VhoverTimescale = 1000;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 0.5f;
|
||||
vd.m_linearDeflectionTimescale = 0.5f;
|
||||
vd.m_angularDeflectionEfficiency = 1;
|
||||
vd.m_angularDeflectionTimescale = 2;
|
||||
vd.m_verticalAttractionEfficiency = 0.9f;
|
||||
vd.m_verticalAttractionTimescale = 2f;
|
||||
vd.m_bankingEfficiency = 1;
|
||||
vd.m_bankingMix = 0.7f;
|
||||
vd.m_bankingTimescale = 2;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BALLOON:
|
||||
vd.m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||
vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
vd.m_linearMotorTimescale = 5;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 6;
|
||||
vd.m_angularMotorDecayTimescale = 10;
|
||||
vd.m_VhoverHeight = 5;
|
||||
vd.m_VhoverEfficiency = 0.8f;
|
||||
vd.m_VhoverTimescale = 10;
|
||||
vd.m_VehicleBuoyancy = 1;
|
||||
vd.m_linearDeflectionEfficiency = 0;
|
||||
vd.m_linearDeflectionTimescale = 5;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 5;
|
||||
vd.m_verticalAttractionEfficiency = 0f;
|
||||
vd.m_verticalAttractionTimescale = 1000f;
|
||||
vd.m_bankingEfficiency = 0;
|
||||
vd.m_bankingMix = 0.7f;
|
||||
vd.m_bankingTimescale = 5;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void SetVehicle(PhysicsActor ph)
|
||||
{
|
||||
if (ph == null)
|
||||
return;
|
||||
ph.SetVehicle(vd);
|
||||
}
|
||||
|
||||
private XmlTextWriter writer;
|
||||
|
||||
private void XWint(string name, int i)
|
||||
{
|
||||
writer.WriteElementString(name, i.ToString());
|
||||
}
|
||||
|
||||
private void XWfloat(string name, float f)
|
||||
{
|
||||
writer.WriteElementString(name, f.ToString(Utils.EnUsCulture));
|
||||
}
|
||||
|
||||
private void XWVector(string name, Vector3 vec)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void XWQuat(string name, Quaternion quat)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
public void ToXml2(XmlTextWriter twriter)
|
||||
{
|
||||
writer = twriter;
|
||||
writer.WriteStartElement("SOGVehicle");
|
||||
|
||||
XWint("TYPE", (int)vd.m_type);
|
||||
XWint("FLAGS", (int)vd.m_flags);
|
||||
|
||||
// Linear properties
|
||||
XWVector("LMDIR", vd.m_linearMotorDirection);
|
||||
XWVector("LMFTIME", vd.m_linearFrictionTimescale);
|
||||
XWfloat("LMDTIME", vd.m_linearMotorDecayTimescale);
|
||||
XWfloat("LMTIME", vd.m_linearMotorTimescale);
|
||||
XWVector("LMOFF", vd.m_linearMotorOffset);
|
||||
|
||||
//Angular properties
|
||||
XWVector("AMDIR", vd.m_angularMotorDirection);
|
||||
XWfloat("AMTIME", vd.m_angularMotorTimescale);
|
||||
XWfloat("AMDTIME", vd.m_angularMotorDecayTimescale);
|
||||
XWVector("AMFTIME", vd.m_angularFrictionTimescale);
|
||||
|
||||
//Deflection properties
|
||||
XWfloat("ADEFF", vd.m_angularDeflectionEfficiency);
|
||||
XWfloat("ADTIME", vd.m_angularDeflectionTimescale);
|
||||
XWfloat("LDEFF", vd.m_linearDeflectionEfficiency);
|
||||
XWfloat("LDTIME", vd.m_linearDeflectionTimescale);
|
||||
|
||||
//Banking properties
|
||||
XWfloat("BEFF", vd.m_bankingEfficiency);
|
||||
XWfloat("BMIX", vd.m_bankingMix);
|
||||
XWfloat("BTIME", vd.m_bankingTimescale);
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
XWfloat("HHEI", vd.m_VhoverHeight);
|
||||
XWfloat("HEFF", vd.m_VhoverEfficiency);
|
||||
XWfloat("HTIME", vd.m_VhoverTimescale);
|
||||
XWfloat("VBUO", vd.m_VehicleBuoyancy);
|
||||
|
||||
//Attractor properties
|
||||
XWfloat("VAEFF", vd.m_verticalAttractionEfficiency);
|
||||
XWfloat("VATIME", vd.m_verticalAttractionTimescale);
|
||||
|
||||
XWQuat("REF_FRAME", vd.m_referenceFrame);
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4792,7 +4792,7 @@ Environment.Exit(1);
|
|||
bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
|
||||
if (wasUsingPhysics)
|
||||
{
|
||||
jointProxyObject.UpdatePrimFlags(false, false, true, false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
|
||||
jointProxyObject.UpdatePrimFlags(false, false, true, false,false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Scenes.Serialization;
|
|||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
|
||||
[Flags]
|
||||
public enum scriptEvents
|
||||
{
|
||||
|
@ -1378,7 +1379,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
m_rootPart.SetParentLocalId(0);
|
||||
AttachmentPoint = (byte)0;
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
|
||||
// must check if buildind should be true or false here
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive,false);
|
||||
HasGroupChanged = true;
|
||||
RootPart.Rezzed = DateTime.Now;
|
||||
RootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
|
@ -1677,22 +1679,32 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public void ApplyPhysics()
|
||||
{
|
||||
// Apply physics to the root prim
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
|
||||
|
||||
// Apply physics to child prims
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
ResetChildPrimPhysicsPositions();
|
||||
|
||||
// Apply physics to the root prim
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, true);
|
||||
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
SceneObjectPart part = parts[i];
|
||||
if (part.LocalId != m_rootPart.LocalId)
|
||||
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive);
|
||||
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, true);
|
||||
}
|
||||
|
||||
// Hack to get the physics scene geometries in the right spot
|
||||
ResetChildPrimPhysicsPositions();
|
||||
// ResetChildPrimPhysicsPositions();
|
||||
if (m_rootPart.PhysActor != null)
|
||||
{
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply physics to the root prim
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1863,6 +1875,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <returns></returns>
|
||||
public SceneObjectGroup Copy(bool userExposed)
|
||||
{
|
||||
m_dupeInProgress = true;
|
||||
SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
|
||||
dupe.m_isBackedUp = false;
|
||||
dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
|
||||
|
@ -1926,13 +1939,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
pbs,
|
||||
newPart.AbsolutePosition,
|
||||
newPart.Scale,
|
||||
newPart.RotationOffset,
|
||||
//newPart.RotationOffset,
|
||||
newPart.GetWorldRotation(),
|
||||
part.PhysActor.IsPhysical,
|
||||
newPart.LocalId);
|
||||
|
||||
newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
|
||||
}
|
||||
}
|
||||
if (dupe.m_rootPart.PhysActor != null && userExposed)
|
||||
dupe.m_rootPart.PhysActor.Building = false; // tell physics to finish building
|
||||
|
||||
if (userExposed)
|
||||
{
|
||||
|
@ -1943,6 +1959,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
ScheduleGroupForFullUpdate();
|
||||
}
|
||||
|
||||
m_dupeInProgress = false;
|
||||
return dupe;
|
||||
}
|
||||
|
||||
|
@ -2950,12 +2967,31 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
RootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
if (parts[i] != RootPart)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
|
||||
}
|
||||
*/
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
|
||||
if (parts[i].UUID != m_rootPart.UUID)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
}
|
||||
|
||||
if (m_rootPart.PhysActor != null)
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
else
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -310,6 +310,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private UUID m_collisionSound;
|
||||
private float m_collisionSoundVolume;
|
||||
|
||||
|
||||
private SOPVehicle m_vehicle = null;
|
||||
|
||||
#endregion Fields
|
||||
|
||||
// ~SceneObjectPart()
|
||||
|
@ -1506,7 +1509,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
/// <param name="rootObjectFlags"></param>
|
||||
/// <param name="VolumeDetectActive"></param>
|
||||
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
|
||||
// public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
|
||||
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
|
||||
{
|
||||
if (!ParentGroup.Scene.CollidablePrims)
|
||||
return;
|
||||
|
@ -1542,7 +1546,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Shape,
|
||||
AbsolutePosition,
|
||||
Scale,
|
||||
RotationOffset,
|
||||
// RotationOffset,
|
||||
GetWorldRotation(), // physics wants world rotation
|
||||
RigidBody,
|
||||
m_localId);
|
||||
}
|
||||
|
@ -1557,8 +1562,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
|
||||
PhysActor.SetMaterial(Material);
|
||||
|
||||
// if root part apply vehicle
|
||||
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
|
||||
m_vehicle.SetVehicle(PhysActor);
|
||||
|
||||
DoPhysicsPropertyUpdate(RigidBody, true);
|
||||
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
|
||||
|
||||
if (!building)
|
||||
PhysActor.Building = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1794,6 +1807,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (!isNew)
|
||||
ParentGroup.Scene.RemovePhysicalPrim(1);
|
||||
|
||||
Velocity = new Vector3(0, 0, 0);
|
||||
Acceleration = new Vector3(0, 0, 0);
|
||||
AngularVelocity = new Vector3(0, 0, 0);
|
||||
|
||||
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
|
||||
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
|
||||
PhysActor.delink();
|
||||
|
@ -3163,17 +3180,61 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public int VehicleType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return (int)Vehicle.TYPE_NONE;
|
||||
else
|
||||
return (int)m_vehicle.Type;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetVehicleType(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVehicleType(int type)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
m_vehicle = null;
|
||||
if (type == (int)Vehicle.TYPE_NONE)
|
||||
{
|
||||
if (_parentID ==0 && PhysActor != null)
|
||||
PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
m_vehicle = new SOPVehicle();
|
||||
m_vehicle.ProcessTypeChange((Vehicle)type);
|
||||
{
|
||||
if (_parentID ==0 && PhysActor != null)
|
||||
PhysActor.VehicleType = type;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVehicleFlags(int param, bool remove)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessVehicleFlags(param, remove);
|
||||
|
||||
if (_parentID ==0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleType = type;
|
||||
PhysActor.VehicleFlags(param, remove);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVehicleFloatParam(int param, float value)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
|
||||
if (_parentID == 0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleFloatParam(param, value);
|
||||
}
|
||||
|
@ -3181,7 +3242,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void SetVehicleVectorParam(int param, Vector3 value)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
|
||||
if (_parentID == 0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleVectorParam(param, value);
|
||||
}
|
||||
|
@ -3189,7 +3255,12 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void SetVehicleRotationParam(int param, Quaternion rotation)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
|
||||
if (_parentID == 0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleRotationParam(param, rotation);
|
||||
}
|
||||
|
@ -3376,13 +3447,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
hasProfileCut = hasDimple; // is it the same thing?
|
||||
}
|
||||
|
||||
public void SetVehicleFlags(int param, bool remove)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleFlags(param, remove);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetGroup(UUID groupID, IClientAPI client)
|
||||
{
|
||||
|
@ -4270,7 +4334,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="SetTemporary"></param>
|
||||
/// <param name="SetPhantom"></param>
|
||||
/// <param name="SetVD"></param>
|
||||
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
|
||||
// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
|
||||
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
|
||||
{
|
||||
bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
|
||||
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
|
||||
|
@ -4288,6 +4353,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// that...
|
||||
// ... if VD is changed, all others are not.
|
||||
// ... if one of the others is changed, VD is not.
|
||||
// do this first
|
||||
if (building && PhysActor != null && PhysActor.Building != building)
|
||||
PhysActor.Building = building;
|
||||
if (SetVD) // VD is active, special logic applies
|
||||
{
|
||||
// State machine logic for VolumeDetect
|
||||
|
@ -4369,11 +4437,17 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Shape,
|
||||
AbsolutePosition,
|
||||
Scale,
|
||||
RotationOffset,
|
||||
// RotationOffset,
|
||||
GetWorldRotation(), //physics wants world rotation like all other functions send
|
||||
UsePhysics,
|
||||
m_localId);
|
||||
|
||||
PhysActor.SetMaterial(Material);
|
||||
|
||||
// if root part apply vehicle
|
||||
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
|
||||
m_vehicle.SetVehicle(PhysActor);
|
||||
|
||||
DoPhysicsPropertyUpdate(UsePhysics, true);
|
||||
|
||||
if (!ParentGroup.IsDeleted)
|
||||
|
@ -4449,6 +4523,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
// m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
|
||||
|
||||
// and last in case we have a new actor and not building
|
||||
if (PhysActor != null && PhysActor.Building != building)
|
||||
PhysActor.Building = building;
|
||||
if (ParentGroup != null)
|
||||
{
|
||||
ParentGroup.HasGroupChanged = true;
|
||||
|
|
|
@ -1843,8 +1843,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
|
||||
|
||||
SitGround = false;
|
||||
|
||||
/* move this down so avatar gets physical in the new position and not where it is siting
|
||||
if (PhysicsActor == null)
|
||||
AddToPhysicalScene(false);
|
||||
*/
|
||||
|
||||
if (ParentID != 0)
|
||||
{
|
||||
|
@ -1879,6 +1882,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
ParentPosition = Vector3.Zero;
|
||||
|
||||
ParentID = 0;
|
||||
|
||||
if (PhysicsActor == null)
|
||||
AddToPhysicalScene(false);
|
||||
|
||||
SendAvatarDataToAllAgents();
|
||||
m_requestedSitTargetID = 0;
|
||||
|
||||
|
@ -1886,6 +1893,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||
}
|
||||
|
||||
else if (PhysicsActor == null)
|
||||
AddToPhysicalScene(false);
|
||||
|
||||
Animator.TrySetMovementAnimation("STAND");
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1736,6 +1736,23 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
return newPrim;
|
||||
}
|
||||
|
||||
private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent,
|
||||
PrimitiveBaseShape pbs, uint localid, byte[] sdata)
|
||||
{
|
||||
Vector3 pos = position;
|
||||
|
||||
OdePrim newPrim;
|
||||
lock (OdeLock)
|
||||
{
|
||||
newPrim = new OdePrim(name, this, pos, parent, pbs, ode, localid, sdata);
|
||||
lock (_prims)
|
||||
_prims.Add(newPrim);
|
||||
}
|
||||
|
||||
return newPrim;
|
||||
}
|
||||
|
||||
|
||||
public void addActivePrim(OdePrim activatePrim)
|
||||
{
|
||||
// adds active prim.. (ones that should be iterated over in collisions_optimized
|
||||
|
@ -1762,6 +1779,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
return result;
|
||||
}
|
||||
|
||||
public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
|
||||
uint localid, byte[] sdata)
|
||||
{
|
||||
PhysicsActor result;
|
||||
|
||||
result = AddPrim(primName, position, parent,
|
||||
pbs, localid, sdata);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override float TimeDilation
|
||||
{
|
||||
get { return m_timeDilation; }
|
||||
|
@ -3412,15 +3440,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
int regionsize = (int) Constants.RegionSize; // visible region size eg. 256(M)
|
||||
|
||||
int heightmapWidth = regionsize + 2; // ODE map size 257 x 257 (Meters) (1 extra
|
||||
int heightmapWidth = regionsize + 2; // ODE map size 258 x 258 (Meters) (1 extra each side)
|
||||
int heightmapHeight = regionsize + 2;
|
||||
|
||||
int heightmapWidthSamples = (int)regionsize + 2; // Sample file size, 258 x 258 samples
|
||||
int heightmapHeightSamples = (int)regionsize + 2;
|
||||
int heightmapWidthSamples = (int)regionsize + 3; // to have 258m we need 259 samples
|
||||
int heightmapHeightSamples = (int)regionsize + 3;
|
||||
|
||||
// Array of height samples for ODE
|
||||
float[] _heightmap;
|
||||
_heightmap = new float[(heightmapWidthSamples * heightmapHeightSamples)]; // loaded samples 258 x 258
|
||||
_heightmap = new float[(heightmapWidthSamples * heightmapHeightSamples)]; // loaded samples 259 x 259
|
||||
|
||||
// Other ODE parameters
|
||||
const float scale = 1.0f;
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
/* Ubit 2012
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// no endian conversion. So can't be use to pass information around diferent cpus with diferent endian
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
|
||||
unsafe public class wstreamer
|
||||
{
|
||||
byte[] buf;
|
||||
int index;
|
||||
byte* src;
|
||||
|
||||
public wstreamer()
|
||||
{
|
||||
buf = new byte[1024];
|
||||
index = 0;
|
||||
}
|
||||
public wstreamer(int size)
|
||||
{
|
||||
buf = new byte[size];
|
||||
index = 0;
|
||||
}
|
||||
|
||||
public byte[] close()
|
||||
{
|
||||
byte[] data = new byte[index];
|
||||
Buffer.BlockCopy(buf, 0, data, 0, index);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void Seek(int pos)
|
||||
{
|
||||
index = pos;
|
||||
}
|
||||
|
||||
public void Seekrel(int pos)
|
||||
{
|
||||
index += pos;
|
||||
}
|
||||
|
||||
public void Wbyte(byte value)
|
||||
{
|
||||
buf[index++] = value;
|
||||
}
|
||||
public void Wshort(short value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wushort(ushort value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wint(int value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wuint(uint value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wlong(long value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wulong(ulong value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
|
||||
public void Wfloat(float value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
|
||||
public void Wdouble(double value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
|
||||
public void Wvector3(Vector3 value)
|
||||
{
|
||||
src = (byte*)&value.X;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Y; // it may have padding ??
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Z;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wquat(Quaternion value)
|
||||
{
|
||||
src = (byte*)&value.X;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Y; // it may have padding ??
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Z;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.W;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe public class rstreamer
|
||||
{
|
||||
private byte[] rbuf;
|
||||
private int ptr;
|
||||
private byte* dst;
|
||||
|
||||
public rstreamer(byte[] data)
|
||||
{
|
||||
rbuf = data;
|
||||
ptr = 0;
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
}
|
||||
|
||||
public void Seek(int pos)
|
||||
{
|
||||
ptr = pos;
|
||||
}
|
||||
|
||||
public void Seekrel(int pos)
|
||||
{
|
||||
ptr += pos;
|
||||
}
|
||||
|
||||
public byte Rbyte()
|
||||
{
|
||||
return (byte)rbuf[ptr++];
|
||||
}
|
||||
|
||||
public short Rshort()
|
||||
{
|
||||
short v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public ushort Rushort()
|
||||
{
|
||||
ushort v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public int Rint()
|
||||
{
|
||||
int v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public uint Ruint()
|
||||
{
|
||||
uint v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public long Rlong()
|
||||
{
|
||||
long v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public ulong Rulong()
|
||||
{
|
||||
ulong v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public float Rfloat()
|
||||
{
|
||||
float v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
|
||||
public double Rdouble()
|
||||
{
|
||||
double v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
|
||||
public Vector3 Rvector3()
|
||||
{
|
||||
Vector3 v;
|
||||
dst = (byte*)&v.X;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Y;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Z;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
|
||||
public Quaternion Rquat()
|
||||
{
|
||||
Quaternion v;
|
||||
dst = (byte*)&v.X;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Y;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Z;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.W;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,5 +65,6 @@ namespace OpenSim.Region.Physics.Manager
|
|||
void releasePinned();
|
||||
void Append(IMesh newMesh);
|
||||
void TransformLinear(float[,] matrix, float[] offset);
|
||||
Vector3 GetCentroid();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,17 @@ namespace OpenSim.Region.Physics.Manager
|
|||
}
|
||||
}
|
||||
|
||||
public struct ContactData
|
||||
{
|
||||
public float mu;
|
||||
public float bounce;
|
||||
|
||||
public ContactData(float _mu, float _bounce)
|
||||
{
|
||||
mu = _mu;
|
||||
bounce = _bounce;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Used to pass collision information to OnCollisionUpdate listeners.
|
||||
/// </summary>
|
||||
|
@ -135,6 +146,8 @@ namespace OpenSim.Region.Physics.Manager
|
|||
/// </summary>
|
||||
public event CollisionUpdate OnCollisionUpdate;
|
||||
|
||||
public virtual void SetVehicle(object vdata) { }
|
||||
|
||||
public event OutOfBounds OnOutOfBounds;
|
||||
#pragma warning restore 67
|
||||
|
||||
|
@ -142,6 +155,13 @@ namespace OpenSim.Region.Physics.Manager
|
|||
{
|
||||
get { return new NullPhysicsActor(); }
|
||||
}
|
||||
|
||||
public virtual bool Building { get; set; }
|
||||
|
||||
public virtual ContactData ContactData
|
||||
{
|
||||
get { return new ContactData(0, 0); }
|
||||
}
|
||||
|
||||
public abstract bool Stopped { get; }
|
||||
|
||||
|
@ -195,6 +215,11 @@ namespace OpenSim.Region.Physics.Manager
|
|||
}
|
||||
}
|
||||
|
||||
public virtual byte[] Serialize(bool PhysIsRunning)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public virtual void RaiseOutOfBounds(Vector3 pos)
|
||||
{
|
||||
// Make a temporary copy of the event to avoid possibility of
|
||||
|
@ -554,5 +579,6 @@ namespace OpenSim.Region.Physics.Manager
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,6 +128,12 @@ namespace OpenSim.Region.Physics.Manager
|
|||
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||
Vector3 size, Quaternion rotation, bool isPhysical, uint localid);
|
||||
|
||||
public virtual PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
|
||||
uint localid, byte[] sdata)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual float TimeDilation
|
||||
{
|
||||
get { return 1.0f; }
|
||||
|
@ -225,7 +231,7 @@ namespace OpenSim.Region.Physics.Manager
|
|||
}
|
||||
|
||||
public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {}
|
||||
|
||||
public virtual void CombineTerrain(float[] heightMap, Vector3 pOffset) {}
|
||||
public virtual void UnCombine(PhysicsScene pScene) {}
|
||||
|
||||
/// <summary>
|
||||
|
@ -263,5 +269,13 @@ namespace OpenSim.Region.Physics.Manager
|
|||
{
|
||||
return new List<ContactResult>();
|
||||
}
|
||||
|
||||
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
|
||||
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
|
||||
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
|
||||
{
|
||||
return new List<ContactResult>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.Manager
|
||||
{
|
||||
|
@ -117,5 +118,47 @@ namespace OpenSim.Region.Physics.Manager
|
|||
NO_DEFLECTION = 16392,
|
||||
LOCK_ROTATION = 32784
|
||||
}
|
||||
|
||||
|
||||
public struct VehicleData
|
||||
{
|
||||
public Vehicle m_type;
|
||||
public VehicleFlag m_flags;
|
||||
|
||||
// Linear properties
|
||||
public Vector3 m_linearMotorDirection;
|
||||
public Vector3 m_linearFrictionTimescale;
|
||||
public float m_linearMotorDecayTimescale;
|
||||
public float m_linearMotorTimescale;
|
||||
public Vector3 m_linearMotorOffset;
|
||||
|
||||
//Angular properties
|
||||
public Vector3 m_angularMotorDirection;
|
||||
public float m_angularMotorTimescale;
|
||||
public float m_angularMotorDecayTimescale;
|
||||
public Vector3 m_angularFrictionTimescale;
|
||||
|
||||
//Deflection properties
|
||||
public float m_angularDeflectionEfficiency;
|
||||
public float m_angularDeflectionTimescale;
|
||||
public float m_linearDeflectionEfficiency;
|
||||
public float m_linearDeflectionTimescale;
|
||||
|
||||
//Banking properties
|
||||
public float m_bankingEfficiency;
|
||||
public float m_bankingMix;
|
||||
public float m_bankingTimescale;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
public float m_VhoverHeight;
|
||||
public float m_VhoverEfficiency;
|
||||
public float m_VhoverTimescale;
|
||||
public float m_VehicleBuoyancy;
|
||||
|
||||
//Attractor properties
|
||||
public float m_verticalAttractionEfficiency;
|
||||
public float m_verticalAttractionTimescale;
|
||||
|
||||
// Axis
|
||||
public Quaternion m_referenceFrame;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,11 +46,36 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
IntPtr m_indicesPtr = IntPtr.Zero;
|
||||
int m_indexCount = 0;
|
||||
public float[] m_normals;
|
||||
Vector3 _centroid;
|
||||
int _centroidDiv;
|
||||
|
||||
private class vertexcomp : IEqualityComparer<Vertex>
|
||||
{
|
||||
public bool Equals(Vertex v1, Vertex v2)
|
||||
{
|
||||
if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
public int GetHashCode(Vertex v)
|
||||
{
|
||||
int a = v.X.GetHashCode();
|
||||
int b = v.Y.GetHashCode();
|
||||
int c = v.Z.GetHashCode();
|
||||
return (a << 16) ^ (b << 8) ^ c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Mesh()
|
||||
{
|
||||
m_vertices = new Dictionary<Vertex, int>();
|
||||
vertexcomp vcomp = new vertexcomp();
|
||||
|
||||
m_vertices = new Dictionary<Vertex, int>(vcomp);
|
||||
m_triangles = new List<Triangle>();
|
||||
_centroid = Vector3.Zero;
|
||||
_centroidDiv = 0;
|
||||
}
|
||||
|
||||
public Mesh Clone()
|
||||
|
@ -61,7 +86,8 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
{
|
||||
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
|
||||
}
|
||||
|
||||
result._centroid = _centroid;
|
||||
result._centroidDiv = _centroidDiv;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -71,15 +97,57 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
||||
// If a vertex of the triangle is not yet in the vertices list,
|
||||
// add it and set its index to the current index count
|
||||
// vertex == seems broken
|
||||
// skip colapsed triangles
|
||||
if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
|
||||
|| (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
|
||||
|| (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_vertices.Count == 0)
|
||||
{
|
||||
_centroidDiv = 0;
|
||||
_centroid = Vector3.Zero;
|
||||
}
|
||||
|
||||
if (!m_vertices.ContainsKey(triangle.v1))
|
||||
{
|
||||
m_vertices[triangle.v1] = m_vertices.Count;
|
||||
_centroid.X += triangle.v1.X;
|
||||
_centroid.Y += triangle.v1.Y;
|
||||
_centroid.Z += triangle.v1.Z;
|
||||
_centroidDiv++;
|
||||
}
|
||||
if (!m_vertices.ContainsKey(triangle.v2))
|
||||
{
|
||||
m_vertices[triangle.v2] = m_vertices.Count;
|
||||
_centroid.X += triangle.v2.X;
|
||||
_centroid.Y += triangle.v2.Y;
|
||||
_centroid.Z += triangle.v2.Z;
|
||||
_centroidDiv++;
|
||||
}
|
||||
if (!m_vertices.ContainsKey(triangle.v3))
|
||||
{
|
||||
m_vertices[triangle.v3] = m_vertices.Count;
|
||||
_centroid.X += triangle.v3.X;
|
||||
_centroid.Y += triangle.v3.Y;
|
||||
_centroid.Z += triangle.v3.Z;
|
||||
_centroidDiv++;
|
||||
}
|
||||
m_triangles.Add(triangle);
|
||||
}
|
||||
|
||||
public Vector3 GetCentroid()
|
||||
{
|
||||
if (_centroidDiv > 0)
|
||||
return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv);
|
||||
else
|
||||
return Vector3.Zero;
|
||||
}
|
||||
|
||||
public void CalcNormals()
|
||||
{
|
||||
int iTriangles = m_triangles.Count;
|
||||
|
|
|
@ -74,6 +74,8 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
#endif
|
||||
|
||||
private bool cacheSculptMaps = true;
|
||||
private bool cacheSculptAlphaMaps = true;
|
||||
|
||||
private string decodedSculptMapPath = null;
|
||||
private bool useMeshiesPhysicsMesh = false;
|
||||
|
||||
|
@ -87,7 +89,16 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
IConfig mesh_config = config.Configs["Mesh"];
|
||||
|
||||
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
||||
|
||||
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
||||
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
cacheSculptAlphaMaps = false;
|
||||
}
|
||||
else
|
||||
cacheSculptAlphaMaps = cacheSculptMaps;
|
||||
|
||||
if(mesh_config != null)
|
||||
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
||||
|
||||
|
@ -268,15 +279,18 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
{
|
||||
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
|
||||
return null;
|
||||
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
|
||||
// don't loose it
|
||||
// primShape.SculptData = Utils.EmptyBytes;
|
||||
}
|
||||
// primShape.SculptDataLoaded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
|
||||
// keep compatible
|
||||
primShape.SculptData = Utils.EmptyBytes;
|
||||
|
||||
int numCoords = coords.Count;
|
||||
|
@ -482,7 +496,8 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
|
||||
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
|
||||
|
||||
if (cacheSculptMaps)
|
||||
if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
|
||||
// don't cache images with alpha channel in linux since mono can't load them correctly)
|
||||
{
|
||||
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
|
||||
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
|
||||
|
|
|
@ -58,28 +58,24 @@ namespace PrimMesher
|
|||
if (bmW == 0 || bmH == 0)
|
||||
throw new Exception("SculptMap: bitmap has no data");
|
||||
|
||||
int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
|
||||
int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
|
||||
|
||||
bool smallMap = bmW * bmH <= numLodPixels;
|
||||
bool needsScaling = false;
|
||||
|
||||
bool smallMap = bmW * bmH <= lod * lod;
|
||||
|
||||
width = bmW;
|
||||
height = bmH;
|
||||
while (width * height > numLodPixels)
|
||||
while (width * height > numLodPixels * 4)
|
||||
{
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
needsScaling = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (needsScaling)
|
||||
bm = ScaleImage(bm, width, height,
|
||||
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
|
||||
bm = ScaleImage(bm, width, height);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
|
@ -87,7 +83,7 @@ namespace PrimMesher
|
|||
throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
|
||||
}
|
||||
|
||||
if (width * height > lod * lod)
|
||||
if (width * height > numLodPixels)
|
||||
{
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
|
@ -144,15 +140,17 @@ namespace PrimMesher
|
|||
int rowNdx, colNdx;
|
||||
int smNdx = 0;
|
||||
|
||||
|
||||
for (rowNdx = 0; rowNdx < numRows; rowNdx++)
|
||||
{
|
||||
List<Coord> row = new List<Coord>(numCols);
|
||||
for (colNdx = 0; colNdx < numCols; colNdx++)
|
||||
{
|
||||
|
||||
if (mirror)
|
||||
row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f));
|
||||
row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
|
||||
else
|
||||
row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f));
|
||||
row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
|
||||
|
||||
++smNdx;
|
||||
}
|
||||
|
@ -161,23 +159,39 @@ namespace PrimMesher
|
|||
return rows;
|
||||
}
|
||||
|
||||
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight,
|
||||
System.Drawing.Drawing2D.InterpolationMode interpMode)
|
||||
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
|
||||
{
|
||||
Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
|
||||
scaledImage.SetResolution(96.0f, 96.0f);
|
||||
|
||||
Graphics grPhoto = Graphics.FromImage(scaledImage);
|
||||
grPhoto.InterpolationMode = interpMode;
|
||||
Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
|
||||
|
||||
Color c;
|
||||
float xscale = srcImage.Width / destWidth;
|
||||
float yscale = srcImage.Height / destHeight;
|
||||
|
||||
float sy = 0.5f;
|
||||
for (int y = 0; y < destHeight; y++)
|
||||
{
|
||||
float sx = 0.5f;
|
||||
for (int x = 0; x < destWidth; x++)
|
||||
{
|
||||
try
|
||||
{
|
||||
c = srcImage.GetPixel((int)(sx), (int)(sy));
|
||||
scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
}
|
||||
|
||||
grPhoto.DrawImage(srcImage,
|
||||
new Rectangle(0, 0, destWidth, destHeight),
|
||||
new Rectangle(0, 0, srcImage.Width, srcImage.Height),
|
||||
GraphicsUnit.Pixel);
|
||||
|
||||
grPhoto.Dispose();
|
||||
sx += xscale;
|
||||
}
|
||||
sy += yscale;
|
||||
}
|
||||
srcImage.Dispose();
|
||||
return scaledImage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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("Ubit Variation")]
|
||||
[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,849 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Ubit 2012
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OdeAPI;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
public class ODEDynamics
|
||||
{
|
||||
public Vehicle Type
|
||||
{
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
private OdePrim rootPrim;
|
||||
private OdeScene _pParentScene;
|
||||
|
||||
// Vehicle properties
|
||||
private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||
private Quaternion m_RollreferenceFrame = Quaternion.Identity; // what hell is this ?
|
||||
|
||||
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||
|
||||
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
|
||||
private Vector3 m_BlockingEndPoint = Vector3.Zero; // not sl
|
||||
|
||||
// Linear properties
|
||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||
private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
private float m_linearMotorDecayTimescale = 120;
|
||||
private float m_linearMotorTimescale = 1000;
|
||||
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||
private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||
|
||||
//Angular properties
|
||||
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||
private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate
|
||||
private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate
|
||||
private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate
|
||||
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||
|
||||
//Deflection properties
|
||||
private float m_angularDeflectionEfficiency = 0;
|
||||
private float m_angularDeflectionTimescale = 1000;
|
||||
private float m_linearDeflectionEfficiency = 0;
|
||||
private float m_linearDeflectionTimescale = 1000;
|
||||
|
||||
//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 = 1000f;
|
||||
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 = 1.0f; // damped
|
||||
private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
|
||||
|
||||
// auxiliar
|
||||
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||
|
||||
private float m_lmEfect = 0; // current linear motor eficiency
|
||||
private float m_amEfect = 0; // current angular motor eficiency
|
||||
|
||||
|
||||
public ODEDynamics(OdePrim rootp)
|
||||
{
|
||||
rootPrim = rootp;
|
||||
_pParentScene = rootPrim._parent_scene;
|
||||
}
|
||||
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
float len;
|
||||
float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE;
|
||||
float timestep = _pParentScene.ODE_STEPSIZE;
|
||||
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_angularDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
m_angularDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||
// if (pValue < timestep) pValue = timestep;
|
||||
// try to make impulses to work a bit better
|
||||
if (pValue < 0.5f) pValue = 0.5f;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
m_angularMotorDecayTimescale = pValue * invtimestep;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
m_angularMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_EFFICIENCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_bankingEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_MIX:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_bankingMix = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
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 < timestep) pValue = timestep;
|
||||
m_VhoverTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_linearDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
m_linearDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||
// if (pValue < timestep) pValue = timestep;
|
||||
// try to make impulses to work a bit better
|
||||
if (pValue < 0.5f) pValue = 0.5f;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
m_linearMotorDecayTimescale = pValue * invtimestep;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
m_linearMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_verticalAttractionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
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:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
len = m_angularMotorDirection.Length();
|
||||
if (len > 12.566f)
|
||||
m_angularMotorDirection *= (12.566f / len);
|
||||
m_amEfect = 1.0f; // turn it on
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
len = m_linearMotorDirection.Length();
|
||||
if (len > 30.0f)
|
||||
m_linearMotorDirection *= (30.0f / len);
|
||||
m_lmEfect = 1.0f; // turn it on
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
len = m_linearMotorOffset.Length();
|
||||
if (len > 100.0f)
|
||||
m_linearMotorOffset *= (100.0f / len);
|
||||
break;
|
||||
}
|
||||
}//end ProcessFloatVehicleParam
|
||||
|
||||
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||
{
|
||||
float len;
|
||||
float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE;
|
||||
float timestep = _pParentScene.ODE_STEPSIZE;
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
if (pValue.Y < timestep) pValue.Y = timestep;
|
||||
if (pValue.Z < timestep) pValue.Z = timestep;
|
||||
|
||||
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
|
||||
len = m_angularMotorDirection.Length();
|
||||
if (len > 12.566f)
|
||||
m_angularMotorDirection *= (12.566f / len);
|
||||
m_amEfect = 1.0f; // turn it on
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
if (pValue.Y < timestep) pValue.Y = timestep;
|
||||
if (pValue.Z < timestep) pValue.Z = timestep;
|
||||
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);
|
||||
len = m_linearMotorDirection.Length();
|
||||
if (len > 30.0f)
|
||||
m_linearMotorDirection *= (30.0f / len);
|
||||
m_lmEfect = 1.0f; // turn it on
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
len = m_linearMotorOffset.Length();
|
||||
if (len > 100.0f)
|
||||
m_linearMotorOffset *= (100.0f / len);
|
||||
break;
|
||||
case Vehicle.BLOCK_EXIT:
|
||||
m_BlockingEndPoint = 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 = Quaternion.Inverse(pValue);
|
||||
break;
|
||||
case Vehicle.ROLL_FRAME:
|
||||
m_RollreferenceFrame = pValue;
|
||||
break;
|
||||
}
|
||||
}//end ProcessRotationVehicleParam
|
||||
|
||||
internal void ProcessVehicleFlags(int pParam, bool remove)
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
m_flags &= ~((VehicleFlag)pParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags |= (VehicleFlag)pParam;
|
||||
}
|
||||
}//end ProcessVehicleFlags
|
||||
|
||||
internal void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
float invtimestep = _pParentScene.ODE_STEPSIZE;
|
||||
m_lmEfect = 0;
|
||||
m_amEfect = 0;
|
||||
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
|
||||
m_BlockingEndPoint = Vector3.Zero;
|
||||
m_RollreferenceFrame = Quaternion.Identity;
|
||||
m_linearMotorOffset = Vector3.Zero;
|
||||
|
||||
m_referenceFrame = Quaternion.Identity;
|
||||
|
||||
// Set Defaults For Type
|
||||
m_type = pType;
|
||||
switch (pType)
|
||||
{
|
||||
case Vehicle.TYPE_NONE:
|
||||
m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
m_linearMotorTimescale = 1000;
|
||||
m_linearMotorDecayTimescale = 120 * invtimestep;
|
||||
m_angularMotorTimescale = 1000;
|
||||
m_angularMotorDecayTimescale = 1000 * invtimestep;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
m_flags = (VehicleFlag)0;
|
||||
break;
|
||||
|
||||
case Vehicle.TYPE_SLED:
|
||||
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
m_linearMotorTimescale = 1000;
|
||||
m_linearMotorDecayTimescale = 120 * invtimestep;
|
||||
m_angularMotorTimescale = 1000;
|
||||
m_angularMotorDecayTimescale = 120 * invtimestep;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 1;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 0;
|
||||
m_linearDeflectionEfficiency = 1;
|
||||
m_linearDeflectionTimescale = 1;
|
||||
m_angularDeflectionEfficiency = 0;
|
||||
m_angularDeflectionTimescale = 1000;
|
||||
m_bankingEfficiency = 0;
|
||||
m_bankingMix = 1;
|
||||
m_bankingTimescale = 10;
|
||||
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_linearMotorTimescale = 1;
|
||||
m_linearMotorDecayTimescale = 60 * invtimestep;
|
||||
m_angularMotorTimescale = 1;
|
||||
m_angularMotorDecayTimescale = 0.8f * invtimestep;
|
||||
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_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BOAT:
|
||||
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
m_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60 * invtimestep;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 4 * invtimestep;
|
||||
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_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP |
|
||||
VehicleFlag.HOVER_WATER_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_AIRPLANE:
|
||||
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||
m_linearMotorTimescale = 2;
|
||||
m_linearMotorDecayTimescale = 60 * invtimestep;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 8 * invtimestep;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 0.5f;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
m_linearDeflectionEfficiency = 0.5f;
|
||||
m_linearDeflectionTimescale = 0.5f;
|
||||
m_angularDeflectionEfficiency = 1;
|
||||
m_angularDeflectionTimescale = 2;
|
||||
m_verticalAttractionEfficiency = 0.9f;
|
||||
m_verticalAttractionTimescale = 2f;
|
||||
m_bankingEfficiency = 1;
|
||||
m_bankingMix = 0.7f;
|
||||
m_bankingTimescale = 2;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.NO_DEFLECTION_UP |
|
||||
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_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60 * invtimestep;
|
||||
m_angularMotorTimescale = 6;
|
||||
m_angularMotorDecayTimescale = 10 * invtimestep;
|
||||
m_VhoverHeight = 5;
|
||||
m_VhoverEfficiency = 0.8f;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 1;
|
||||
m_linearDeflectionEfficiency = 0;
|
||||
m_linearDeflectionTimescale = 5 * invtimestep;
|
||||
m_angularDeflectionEfficiency = 0;
|
||||
m_angularDeflectionTimescale = 5;
|
||||
m_verticalAttractionEfficiency = 0f;
|
||||
m_verticalAttractionTimescale = 1000f;
|
||||
m_bankingEfficiency = 0;
|
||||
m_bankingMix = 0.7f;
|
||||
m_bankingTimescale = 5;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
}//end SetDefaultsForType
|
||||
|
||||
internal void Stop()
|
||||
{
|
||||
m_lmEfect = 0;
|
||||
m_amEfect = 0;
|
||||
}
|
||||
|
||||
public static Vector3 Xrot(Quaternion rot)
|
||||
{
|
||||
Vector3 vec;
|
||||
rot.Normalize(); // just in case
|
||||
vec.X = 2 * (rot.X * rot.X + rot.W * rot.W) - 1;
|
||||
vec.Y = 2 * (rot.X * rot.Y + rot.Z * rot.W);
|
||||
vec.Z = 2 * (rot.X * rot.Z - rot.Y * rot.W);
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static Vector3 Zrot(Quaternion rot)
|
||||
{
|
||||
Vector3 vec;
|
||||
rot.Normalize(); // just in case
|
||||
vec.X = 2 * (rot.X * rot.Z + rot.Y * rot.W);
|
||||
vec.Y = 2 * (rot.Y * rot.Z - rot.X * rot.W);
|
||||
vec.Z = 2 * (rot.Z * rot.Z + rot.W * rot.W) - 1;
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
private const float halfpi = 0.5f * (float)Math.PI;
|
||||
|
||||
public static Vector3 ubitRot2Euler(Quaternion rot)
|
||||
{
|
||||
// returns roll in X
|
||||
// pitch in Y
|
||||
// yaw in Z
|
||||
Vector3 vec;
|
||||
|
||||
// assuming rot is normalised
|
||||
// rot.Normalize();
|
||||
|
||||
float zX = rot.X * rot.Z + rot.Y * rot.W;
|
||||
|
||||
if (zX < -0.49999f)
|
||||
{
|
||||
vec.X = 0;
|
||||
vec.Y = -halfpi;
|
||||
vec.Z = (float)(-2d * Math.Atan(rot.X / rot.W));
|
||||
}
|
||||
else if (zX > 0.49999f)
|
||||
{
|
||||
vec.X = 0;
|
||||
vec.Y = halfpi;
|
||||
vec.Z = (float)(2d * Math.Atan(rot.X / rot.W));
|
||||
}
|
||||
else
|
||||
{
|
||||
vec.Y = (float)Math.Asin(2 * zX);
|
||||
|
||||
float sqw = rot.W * rot.W;
|
||||
|
||||
float minuszY = rot.X * rot.W - rot.Y * rot.Z;
|
||||
float zZ = rot.Z * rot.Z + sqw - 0.5f;
|
||||
|
||||
vec.X = (float)Math.Atan2(minuszY, zZ);
|
||||
|
||||
float yX = rot.Z * rot.W - rot.X * rot.Y; //( have negative ?)
|
||||
float yY = rot.X * rot.X + sqw - 0.5f;
|
||||
vec.Z = (float)Math.Atan2(yX, yY);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static void GetRollPitch(Quaternion rot, out float roll, out float pitch)
|
||||
{
|
||||
// assuming rot is normalised
|
||||
// rot.Normalize();
|
||||
|
||||
float zX = rot.X * rot.Z + rot.Y * rot.W;
|
||||
|
||||
if (zX < -0.49999f)
|
||||
{
|
||||
roll = 0;
|
||||
pitch = -halfpi;
|
||||
}
|
||||
else if (zX > 0.49999f)
|
||||
{
|
||||
roll = 0;
|
||||
pitch = halfpi;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = (float)Math.Asin(2 * zX);
|
||||
|
||||
float minuszY = rot.X * rot.W - rot.Y * rot.Z;
|
||||
float zZ = rot.Z * rot.Z + rot.W * rot.W - 0.5f;
|
||||
|
||||
roll = (float)Math.Atan2(minuszY, zZ);
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
internal void Step()//float pTimestep)
|
||||
{
|
||||
IntPtr Body = rootPrim.Body;
|
||||
|
||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||
Quaternion objrotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||
Quaternion rotq = objrotq; // rotq = rotation of object
|
||||
rotq *= m_referenceFrame; // rotq is now rotation in vehicle reference frame
|
||||
Quaternion irotq = Quaternion.Inverse(rotq);
|
||||
|
||||
d.Vector3 dvtmp;
|
||||
Vector3 tmpV;
|
||||
Vector3 curVel; // velocity in world
|
||||
Vector3 curAngVel; // angular velocity in world
|
||||
Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame
|
||||
Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in vehicle frame
|
||||
d.Vector3 dtorque = new d.Vector3();
|
||||
|
||||
dvtmp = d.BodyGetLinearVel(Body);
|
||||
curVel.X = dvtmp.X;
|
||||
curVel.Y = dvtmp.Y;
|
||||
curVel.Z = dvtmp.Z;
|
||||
Vector3 curLocalVel = curVel * irotq; // current velocity in local
|
||||
|
||||
dvtmp = d.BodyGetAngularVel(Body);
|
||||
curAngVel.X = dvtmp.X;
|
||||
curAngVel.Y = dvtmp.Y;
|
||||
curAngVel.Z = dvtmp.Z;
|
||||
Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local
|
||||
|
||||
// linear motor
|
||||
if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000)
|
||||
{
|
||||
tmpV = m_linearMotorDirection - curLocalVel; // velocity error
|
||||
tmpV *= m_lmEfect / m_linearMotorTimescale; // error to correct in this timestep
|
||||
tmpV *= rotq; // to world
|
||||
|
||||
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
|
||||
tmpV.Z = 0;
|
||||
|
||||
if (m_linearMotorOffset.X != 0 || m_linearMotorOffset.Y != 0 || m_linearMotorOffset.Z != 0)
|
||||
{
|
||||
// have offset, do it now
|
||||
tmpV *= rootPrim.Mass;
|
||||
d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
force.X += tmpV.X;
|
||||
force.Y += tmpV.Y;
|
||||
force.Z += tmpV.Z;
|
||||
}
|
||||
m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
|
||||
}
|
||||
else
|
||||
m_lmEfect = 0;
|
||||
|
||||
// friction
|
||||
if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
|
||||
{
|
||||
tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X;
|
||||
tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y;
|
||||
tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z;
|
||||
tmpV *= rotq; // to world
|
||||
force.X += tmpV.X;
|
||||
force.Y += tmpV.Y;
|
||||
force.Z += tmpV.Z;
|
||||
}
|
||||
|
||||
// hover
|
||||
if (m_VhoverTimescale < 300)
|
||||
{
|
||||
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||
|
||||
// default to global
|
||||
float perr = m_VhoverHeight - pos.Z;;
|
||||
|
||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||
{
|
||||
perr += _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
|
||||
}
|
||||
else if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||
{
|
||||
perr += _pParentScene.GetWaterLevel();
|
||||
}
|
||||
else if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == 0)
|
||||
{
|
||||
float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
|
||||
float w = _pParentScene.GetWaterLevel();
|
||||
if (t > w)
|
||||
perr += t;
|
||||
else
|
||||
perr += w;
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > 0)
|
||||
{
|
||||
force.Z += (perr / m_VhoverTimescale / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency) / _pParentScene.ODE_STEPSIZE;
|
||||
force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
|
||||
}
|
||||
else // no buoyancy
|
||||
force.Z += _pParentScene.gravityz;
|
||||
}
|
||||
else
|
||||
{
|
||||
// default gravity and buoancy
|
||||
force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
|
||||
}
|
||||
|
||||
// linear deflection
|
||||
if (m_linearDeflectionEfficiency > 0)
|
||||
{
|
||||
float len = curVel.Length();
|
||||
Vector3 atAxis;
|
||||
atAxis = Xrot(rotq); // where are we pointing to
|
||||
atAxis *= len; // make it same size as world velocity vector
|
||||
tmpV = -atAxis; // oposite direction
|
||||
atAxis -= curVel; // error to one direction
|
||||
len = atAxis.LengthSquared();
|
||||
tmpV -= curVel; // error to oposite
|
||||
float lens = tmpV.LengthSquared();
|
||||
if (len > 0.01 || lens > 0.01) // do nothing if close enougth
|
||||
{
|
||||
if (len < lens)
|
||||
tmpV = atAxis;
|
||||
|
||||
tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
|
||||
force.X += tmpV.X;
|
||||
force.Y += tmpV.Y;
|
||||
if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0)
|
||||
force.Z += tmpV.Z;
|
||||
}
|
||||
}
|
||||
|
||||
// angular motor
|
||||
if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000)
|
||||
{
|
||||
tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error
|
||||
tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep
|
||||
torque.X += tmpV.X;
|
||||
torque.Y += tmpV.Y;
|
||||
torque.Z += tmpV.Z;
|
||||
m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale);
|
||||
}
|
||||
else
|
||||
m_amEfect = 0;
|
||||
|
||||
// angular friction
|
||||
if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
|
||||
{
|
||||
torque.X -= curLocalAngVel.X / m_angularFrictionTimescale.X;
|
||||
torque.Y -= curLocalAngVel.Y / m_angularFrictionTimescale.Y;
|
||||
torque.Z -= curLocalAngVel.Z / m_angularFrictionTimescale.Z;
|
||||
}
|
||||
|
||||
// angular deflection
|
||||
if (m_angularDeflectionEfficiency > 0)
|
||||
{
|
||||
Vector3 dirv;
|
||||
|
||||
if (curLocalVel.X > 0.01f)
|
||||
dirv = curLocalVel;
|
||||
else if (curLocalVel.X < -0.01f)
|
||||
// use oposite
|
||||
dirv = -curLocalVel;
|
||||
else
|
||||
{
|
||||
// make it fall into small positive x case
|
||||
dirv.X = 0.01f;
|
||||
dirv.Y = curLocalVel.Y;
|
||||
dirv.Z = curLocalVel.Z;
|
||||
}
|
||||
|
||||
float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
|
||||
|
||||
if (Math.Abs(dirv.Z) > 0.01)
|
||||
{
|
||||
torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp;
|
||||
}
|
||||
|
||||
if (Math.Abs(dirv.Y) > 0.01)
|
||||
{
|
||||
torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp;
|
||||
}
|
||||
}
|
||||
|
||||
// vertical atractor
|
||||
if (m_verticalAttractionTimescale < 300)
|
||||
{
|
||||
float roll;
|
||||
float pitch;
|
||||
|
||||
GetRollPitch(irotq, out roll, out pitch);
|
||||
|
||||
float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
|
||||
float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
|
||||
|
||||
if (Math.Abs(roll) > 0.01) // roll
|
||||
{
|
||||
torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2;
|
||||
}
|
||||
|
||||
if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch
|
||||
{
|
||||
torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2;
|
||||
}
|
||||
|
||||
if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01)
|
||||
{
|
||||
float broll = roll * m_bankingEfficiency; ;
|
||||
if (m_bankingMix != 0)
|
||||
{
|
||||
float vfact = Math.Abs(curLocalVel.X) / 10.0f;
|
||||
if (vfact > 1.0f) vfact = 1.0f;
|
||||
if (curLocalVel.X >= 0)
|
||||
broll *= ((1 - m_bankingMix) + vfact);
|
||||
else
|
||||
broll *= -((1 - m_bankingMix) + vfact);
|
||||
}
|
||||
broll = (broll - curLocalAngVel.Z) / m_bankingTimescale;
|
||||
// torque.Z += broll;
|
||||
|
||||
// make z rot be in world Z not local as seems to be in sl
|
||||
tmpV.X = 0;
|
||||
tmpV.Y = 0;
|
||||
tmpV.Z = broll;
|
||||
tmpV *= irotq;
|
||||
|
||||
torque.X += tmpV.X;
|
||||
torque.Y += tmpV.Y;
|
||||
torque.Z += tmpV.Z;
|
||||
}
|
||||
}
|
||||
|
||||
d.Mass dmass;
|
||||
d.BodyGetMass(Body,out dmass);
|
||||
|
||||
if (force.X != 0 || force.Y != 0 || force.Z != 0)
|
||||
{
|
||||
force *= dmass.mass;
|
||||
d.BodySetForce(Body, force.X, force.Y, force.Z);
|
||||
}
|
||||
|
||||
if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)
|
||||
{
|
||||
torque *= m_referenceFrame; // to object frame
|
||||
dtorque.X = torque.X;
|
||||
dtorque.Y = torque.Y;
|
||||
dtorque.Z = torque.Z;
|
||||
|
||||
d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque);
|
||||
d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,443 @@
|
|||
/*
|
||||
* 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 OdeAPI;
|
||||
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 ray requests
|
||||
/// </summary>
|
||||
protected OpenSim.Framework.LocklessQueue<ODERayRequest> m_PendingRequests = new OpenSim.Framework.LocklessQueue<ODERayRequest>();
|
||||
|
||||
/// <summary>
|
||||
/// Scene that created this object.
|
||||
/// </summary>
|
||||
private OdeScene m_scene;
|
||||
|
||||
IntPtr ray;
|
||||
|
||||
private const int ColisionContactGeomsPerTest = 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;
|
||||
ray = d.CreateRay(IntPtr.Zero, 1.0f);
|
||||
}
|
||||
|
||||
/// <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, RayCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = IntPtr.Zero;
|
||||
req.callbackMethod = retMethod;
|
||||
req.Count = 0;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
|
||||
m_PendingRequests.Enqueue(req);
|
||||
}
|
||||
|
||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = geom;
|
||||
req.callbackMethod = retMethod;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
req.Count = 0;
|
||||
|
||||
m_PendingRequests.Enqueue(req);
|
||||
}
|
||||
|
||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = IntPtr.Zero;
|
||||
req.callbackMethod = retMethod;
|
||||
req.Count = 0;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
|
||||
m_PendingRequests.Enqueue(req);
|
||||
}
|
||||
|
||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = geom;
|
||||
req.callbackMethod = retMethod;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
req.Count = 0;
|
||||
|
||||
m_PendingRequests.Enqueue(req);
|
||||
}
|
||||
|
||||
/// <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="count"></param>
|
||||
/// <param name="retMethod">Return method to send the results</param>
|
||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = IntPtr.Zero;
|
||||
req.callbackMethod = retMethod;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
req.Count = count;
|
||||
|
||||
m_PendingRequests.Enqueue(req);
|
||||
}
|
||||
|
||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = geom;
|
||||
req.callbackMethod = retMethod;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
req.Count = count;
|
||||
|
||||
m_PendingRequests.Enqueue(req);
|
||||
}
|
||||
|
||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = IntPtr.Zero;
|
||||
req.callbackMethod = retMethod;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
req.Count = count;
|
||||
|
||||
m_PendingRequests.Enqueue(req);
|
||||
}
|
||||
|
||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
|
||||
{
|
||||
ODERayRequest req = new ODERayRequest();
|
||||
req.geom = geom;
|
||||
req.callbackMethod = retMethod;
|
||||
req.length = length;
|
||||
req.Normal = direction;
|
||||
req.Origin = position;
|
||||
req.Count = count;
|
||||
|
||||
m_PendingRequests.Enqueue(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;
|
||||
|
||||
if (m_PendingRequests.Count <= 0)
|
||||
return 0;
|
||||
|
||||
if (m_scene.ContactgeomsArray == IntPtr.Zero) // oops something got wrong or scene isn't ready still
|
||||
{
|
||||
m_PendingRequests.Clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ODERayRequest req;
|
||||
|
||||
int i = 50; // arbitary limit of processed tests per frame
|
||||
|
||||
while(m_PendingRequests.Dequeue(out req))
|
||||
{
|
||||
if (req.geom == IntPtr.Zero)
|
||||
doSpaceRay(req);
|
||||
else
|
||||
doGeomRay(req);
|
||||
if(--i < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
lock (m_contactResults)
|
||||
m_contactResults.Clear();
|
||||
|
||||
return System.Environment.TickCount - time;
|
||||
}
|
||||
/// <summary>
|
||||
/// Method that actually initiates the raycast with full top space
|
||||
/// </summary>
|
||||
/// <param name="req"></param>
|
||||
private void doSpaceRay(ODERayRequest req)
|
||||
{
|
||||
// Create the ray
|
||||
// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
|
||||
d.GeomRaySetLength(ray, 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.TopSpace, ray, IntPtr.Zero, nearCallback);
|
||||
|
||||
// Remove Ray
|
||||
// d.GeomDestroy(ray);
|
||||
|
||||
if (req.callbackMethod == null)
|
||||
return;
|
||||
|
||||
if (req.callbackMethod is RaycastCallback)
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
|
||||
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
((RayCallback)req.callbackMethod)(m_contactResults);
|
||||
lock (m_PendingRequests)
|
||||
m_contactResults.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method that actually initiates the raycast with a geom
|
||||
/// </summary>
|
||||
/// <param name="req"></param>
|
||||
private void doGeomRay(ODERayRequest req)
|
||||
{
|
||||
// Create the ray
|
||||
// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
|
||||
d.GeomRaySetLength(ray, 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(req.geom, ray, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
|
||||
|
||||
// Remove Ray
|
||||
// d.GeomDestroy(ray);
|
||||
|
||||
if (req.callbackMethod == null)
|
||||
return;
|
||||
|
||||
if (req.callbackMethod is RaycastCallback)
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
|
||||
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
||||
}
|
||||
else
|
||||
{
|
||||
((RayCallback)req.callbackMethod)(m_contactResults);
|
||||
lock (m_PendingRequests)
|
||||
m_contactResults.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
|
||||
{
|
||||
IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
|
||||
if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest)
|
||||
return false;
|
||||
|
||||
IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
|
||||
newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom));
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is the standard Near. g2 is the ray
|
||||
private void near(IntPtr space, IntPtr g1, IntPtr g2)
|
||||
{
|
||||
//Don't test against heightfield Geom, or you'll be sorry!
|
||||
// Exclude heightfield geom
|
||||
|
||||
if (g1 == IntPtr.Zero || g1 == g2)
|
||||
return;
|
||||
|
||||
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
|
||||
return;
|
||||
|
||||
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
|
||||
if (d.GeomIsSpace(g1))
|
||||
{
|
||||
try
|
||||
{
|
||||
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
try
|
||||
{
|
||||
count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
|
||||
}
|
||||
catch (SEHException)
|
||||
{
|
||||
m_log.Error("[PHYSICS Ray]: 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 Ray]: Unable to collide test an object: {0}", e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
PhysicsActor p1 = null;
|
||||
|
||||
if (g1 != IntPtr.Zero)
|
||||
m_scene.actor_name_map.TryGetValue(g1, out p1);
|
||||
|
||||
d.ContactGeom curcontact = new d.ContactGeom();
|
||||
// Loop over contacts, build results.
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (!GetCurContactGeom(i, ref curcontact))
|
||||
break;
|
||||
if (p1 != null) {
|
||||
if (p1 is OdePrim)
|
||||
{
|
||||
ContactResult collisionresult = new ContactResult();
|
||||
|
||||
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
|
||||
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
||||
collisionresult.Depth = curcontact.depth;
|
||||
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
||||
curcontact.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 ODERayRequest
|
||||
{
|
||||
public IntPtr geom;
|
||||
public Vector3 Origin;
|
||||
public Vector3 Normal;
|
||||
public int Count;
|
||||
public float length;
|
||||
public object callbackMethod;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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.Threading;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OdeAPI;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// ODE plugin
|
||||
/// </summary>
|
||||
public class OdePlugin : IPhysicsPlugin
|
||||
{
|
||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private OdeScene m_scene;
|
||||
|
||||
public bool Init()
|
||||
{
|
||||
if (d.InitODE2(0) != 0)
|
||||
{
|
||||
if (d.AllocateODEDataForThread(~0U) == 0)
|
||||
{
|
||||
d.CloseODE();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public PhysicsScene GetScene(String sceneIdentifier)
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
m_scene = new OdeScene(sceneIdentifier);
|
||||
}
|
||||
return (m_scene);
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return ("UbitODE");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
d.CloseODE();
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
<configuration>
|
||||
<dllmap os="osx" dll="ode" target="libode.dylib" />
|
||||
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="ode" target="libode-x86_64" />
|
||||
<dllmap os="!windows,osx" cpu="x86" dll="ode" target="libode" />
|
||||
<dllmap os="!windows,osx" cpu="ppc64" dll="ode" target="libode-ppc64" />
|
||||
<dllmap os="!windows,osx" cpu="s390x" dll="ode" target="libode-s390x" />
|
||||
</configuration>
|
Binary file not shown.
Binary file not shown.
38
prebuild.xml
38
prebuild.xml
|
@ -6,7 +6,7 @@
|
|||
<CompilerDefines>TRACE;DEBUG</CompilerDefines>
|
||||
<OptimizeCode>false</OptimizeCode>
|
||||
<CheckUnderflowOverflow>false</CheckUnderflowOverflow>
|
||||
<AllowUnsafe>false</AllowUnsafe>
|
||||
<AllowUnsafe>true</AllowUnsafe>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<WarningsAsErrors>false</WarningsAsErrors>
|
||||
<SuppressWarnings/>
|
||||
|
@ -606,6 +606,36 @@
|
|||
</Files>
|
||||
</Project>
|
||||
|
||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.UbitOdePlugin" path="OpenSim/Region/Physics/UbitOdePlugin" 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" path="../../../../bin/"/>
|
||||
<Reference name="Nini" path="../../../../bin/"/>
|
||||
|
||||
<Reference name="OpenSim.Framework"/>
|
||||
<Reference name="OpenSim.Framework.Console"/>
|
||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||
<Reference name="log4net" path="../../../../bin/"/>
|
||||
|
||||
<Files>
|
||||
<Match pattern="*.cs" recurse="true">
|
||||
<Exclude name="Tests" pattern="Tests"/>
|
||||
</Match>
|
||||
</Files>
|
||||
</Project>
|
||||
|
||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
|
@ -3316,16 +3346,12 @@
|
|||
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
|
||||
<Reference name="XMLRPC" path="../../../bin/"/>
|
||||
<Reference name="OpenSim.Framework"/>
|
||||
<Reference name="OpenSim.Framework.Communications"/>
|
||||
<Reference name="OpenSim.Framework.Console"/>
|
||||
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
|
||||
<Reference name="OpenSim.Region.CoreModules"/>
|
||||
<Reference name="OpenSim.Region.Framework"/>
|
||||
<Reference name="OpenSim.Region.OptionalModules"/>
|
||||
<Reference name="OpenSim.Region.ScriptEngine.Shared"/>
|
||||
<Reference name="OpenSim.Region.ScriptEngine.XEngine"/>
|
||||
<Reference name="OpenSim.Services.Interfaces"/>
|
||||
<Reference name="OpenSim.Services.AvatarService"/>
|
||||
<Reference name="OpenSim.Region.ScriptEngine.Shared"/>
|
||||
<Reference name="OpenSim.Tests.Common"/>
|
||||
<Files>
|
||||
<Match pattern="*.cs" recurse="false"/>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
bin\Prebuild.exe /target nant
|
||||
bin\Prebuild.exe /target vs2008
|
||||
echo C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild opensim.sln > compile.bat
|
||||
echo C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild OpenSim.sln > compile.bat
|
||||
|
||||
|
|
Loading…
Reference in New Issue