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;
|
so.AttachedAvatar = UUID.Zero;
|
||||||
rootPart.SetParentLocalId(0);
|
rootPart.SetParentLocalId(0);
|
||||||
so.ClearPartAttachmentData();
|
so.ClearPartAttachmentData();
|
||||||
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive);
|
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
|
||||||
so.HasGroupChanged = true;
|
so.HasGroupChanged = true;
|
||||||
rootPart.Rezzed = DateTime.Now;
|
rootPart.Rezzed = DateTime.Now;
|
||||||
rootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
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);
|
bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
|
||||||
if (wasUsingPhysics)
|
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
|
namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum scriptEvents
|
public enum scriptEvents
|
||||||
{
|
{
|
||||||
|
@ -1378,7 +1379,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_rootPart.SetParentLocalId(0);
|
m_rootPart.SetParentLocalId(0);
|
||||||
AttachmentPoint = (byte)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;
|
HasGroupChanged = true;
|
||||||
RootPart.Rezzed = DateTime.Now;
|
RootPart.Rezzed = DateTime.Now;
|
||||||
RootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
RootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||||
|
@ -1677,22 +1679,32 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ApplyPhysics()
|
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();
|
SceneObjectPart[] parts = m_parts.GetArray();
|
||||||
if (parts.Length > 1)
|
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++)
|
for (int i = 0; i < parts.Length; i++)
|
||||||
{
|
{
|
||||||
SceneObjectPart part = parts[i];
|
SceneObjectPart part = parts[i];
|
||||||
if (part.LocalId != m_rootPart.LocalId)
|
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
|
// 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>
|
/// <returns></returns>
|
||||||
public SceneObjectGroup Copy(bool userExposed)
|
public SceneObjectGroup Copy(bool userExposed)
|
||||||
{
|
{
|
||||||
|
m_dupeInProgress = true;
|
||||||
SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
|
SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
|
||||||
dupe.m_isBackedUp = false;
|
dupe.m_isBackedUp = false;
|
||||||
dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
|
dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
|
||||||
|
@ -1926,13 +1939,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
pbs,
|
pbs,
|
||||||
newPart.AbsolutePosition,
|
newPart.AbsolutePosition,
|
||||||
newPart.Scale,
|
newPart.Scale,
|
||||||
newPart.RotationOffset,
|
//newPart.RotationOffset,
|
||||||
|
newPart.GetWorldRotation(),
|
||||||
part.PhysActor.IsPhysical,
|
part.PhysActor.IsPhysical,
|
||||||
newPart.LocalId);
|
newPart.LocalId);
|
||||||
|
|
||||||
newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
|
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)
|
if (userExposed)
|
||||||
{
|
{
|
||||||
|
@ -1943,6 +1959,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScheduleGroupForFullUpdate();
|
ScheduleGroupForFullUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_dupeInProgress = false;
|
||||||
return dupe;
|
return dupe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2950,12 +2967,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
RootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
|
RootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
|
||||||
for (int i = 0; i < parts.Length; i++)
|
for (int i = 0; i < parts.Length; i++)
|
||||||
{
|
{
|
||||||
if (parts[i] != RootPart)
|
if (parts[i] != RootPart)
|
||||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
|
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 UUID m_collisionSound;
|
||||||
private float m_collisionSoundVolume;
|
private float m_collisionSoundVolume;
|
||||||
|
|
||||||
|
|
||||||
|
private SOPVehicle m_vehicle = null;
|
||||||
|
|
||||||
#endregion Fields
|
#endregion Fields
|
||||||
|
|
||||||
// ~SceneObjectPart()
|
// ~SceneObjectPart()
|
||||||
|
@ -1506,7 +1509,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rootObjectFlags"></param>
|
/// <param name="rootObjectFlags"></param>
|
||||||
/// <param name="VolumeDetectActive"></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)
|
if (!ParentGroup.Scene.CollidablePrims)
|
||||||
return;
|
return;
|
||||||
|
@ -1542,7 +1546,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Shape,
|
Shape,
|
||||||
AbsolutePosition,
|
AbsolutePosition,
|
||||||
Scale,
|
Scale,
|
||||||
RotationOffset,
|
// RotationOffset,
|
||||||
|
GetWorldRotation(), // physics wants world rotation
|
||||||
RigidBody,
|
RigidBody,
|
||||||
m_localId);
|
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.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
|
||||||
PhysActor.SetMaterial(Material);
|
PhysActor.SetMaterial(Material);
|
||||||
|
|
||||||
|
// if root part apply vehicle
|
||||||
|
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
|
||||||
|
m_vehicle.SetVehicle(PhysActor);
|
||||||
|
|
||||||
DoPhysicsPropertyUpdate(RigidBody, true);
|
DoPhysicsPropertyUpdate(RigidBody, true);
|
||||||
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
|
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
|
||||||
|
|
||||||
|
if (!building)
|
||||||
|
PhysActor.Building = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1794,6 +1807,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (!isNew)
|
if (!isNew)
|
||||||
ParentGroup.Scene.RemovePhysicalPrim(1);
|
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.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
|
||||||
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
|
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
|
||||||
PhysActor.delink();
|
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)
|
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)
|
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);
|
PhysActor.VehicleFloatParam(param, value);
|
||||||
}
|
}
|
||||||
|
@ -3181,7 +3242,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void SetVehicleVectorParam(int param, Vector3 value)
|
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);
|
PhysActor.VehicleVectorParam(param, value);
|
||||||
}
|
}
|
||||||
|
@ -3189,7 +3255,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void SetVehicleRotationParam(int param, Quaternion rotation)
|
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);
|
PhysActor.VehicleRotationParam(param, rotation);
|
||||||
}
|
}
|
||||||
|
@ -3376,13 +3447,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
hasProfileCut = hasDimple; // is it the same thing?
|
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)
|
public void SetGroup(UUID groupID, IClientAPI client)
|
||||||
{
|
{
|
||||||
|
@ -4270,7 +4334,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="SetTemporary"></param>
|
/// <param name="SetTemporary"></param>
|
||||||
/// <param name="SetPhantom"></param>
|
/// <param name="SetPhantom"></param>
|
||||||
/// <param name="SetVD"></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 wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
|
||||||
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
|
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
|
||||||
|
@ -4288,6 +4353,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// that...
|
// that...
|
||||||
// ... if VD is changed, all others are not.
|
// ... if VD is changed, all others are not.
|
||||||
// ... if one of the others is changed, VD is 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
|
if (SetVD) // VD is active, special logic applies
|
||||||
{
|
{
|
||||||
// State machine logic for VolumeDetect
|
// State machine logic for VolumeDetect
|
||||||
|
@ -4369,11 +4437,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Shape,
|
Shape,
|
||||||
AbsolutePosition,
|
AbsolutePosition,
|
||||||
Scale,
|
Scale,
|
||||||
RotationOffset,
|
// RotationOffset,
|
||||||
|
GetWorldRotation(), //physics wants world rotation like all other functions send
|
||||||
UsePhysics,
|
UsePhysics,
|
||||||
m_localId);
|
m_localId);
|
||||||
|
|
||||||
PhysActor.SetMaterial(Material);
|
PhysActor.SetMaterial(Material);
|
||||||
|
|
||||||
|
// if root part apply vehicle
|
||||||
|
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
|
||||||
|
m_vehicle.SetVehicle(PhysActor);
|
||||||
|
|
||||||
DoPhysicsPropertyUpdate(UsePhysics, true);
|
DoPhysicsPropertyUpdate(UsePhysics, true);
|
||||||
|
|
||||||
if (!ParentGroup.IsDeleted)
|
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());
|
// 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)
|
if (ParentGroup != null)
|
||||||
{
|
{
|
||||||
ParentGroup.HasGroupChanged = true;
|
ParentGroup.HasGroupChanged = true;
|
||||||
|
|
|
@ -1843,8 +1843,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
|
// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
|
||||||
|
|
||||||
SitGround = false;
|
SitGround = false;
|
||||||
|
|
||||||
|
/* move this down so avatar gets physical in the new position and not where it is siting
|
||||||
if (PhysicsActor == null)
|
if (PhysicsActor == null)
|
||||||
AddToPhysicalScene(false);
|
AddToPhysicalScene(false);
|
||||||
|
*/
|
||||||
|
|
||||||
if (ParentID != 0)
|
if (ParentID != 0)
|
||||||
{
|
{
|
||||||
|
@ -1879,6 +1882,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ParentPosition = Vector3.Zero;
|
ParentPosition = Vector3.Zero;
|
||||||
|
|
||||||
ParentID = 0;
|
ParentID = 0;
|
||||||
|
|
||||||
|
if (PhysicsActor == null)
|
||||||
|
AddToPhysicalScene(false);
|
||||||
|
|
||||||
SendAvatarDataToAllAgents();
|
SendAvatarDataToAllAgents();
|
||||||
m_requestedSitTargetID = 0;
|
m_requestedSitTargetID = 0;
|
||||||
|
|
||||||
|
@ -1886,6 +1893,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (PhysicsActor == null)
|
||||||
|
AddToPhysicalScene(false);
|
||||||
|
|
||||||
Animator.TrySetMovementAnimation("STAND");
|
Animator.TrySetMovementAnimation("STAND");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1736,6 +1736,23 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
return newPrim;
|
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)
|
public void addActivePrim(OdePrim activatePrim)
|
||||||
{
|
{
|
||||||
// adds active prim.. (ones that should be iterated over in collisions_optimized
|
// adds active prim.. (ones that should be iterated over in collisions_optimized
|
||||||
|
@ -1762,6 +1779,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
return result;
|
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
|
public override float TimeDilation
|
||||||
{
|
{
|
||||||
get { return m_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 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 heightmapHeight = regionsize + 2;
|
||||||
|
|
||||||
int heightmapWidthSamples = (int)regionsize + 2; // Sample file size, 258 x 258 samples
|
int heightmapWidthSamples = (int)regionsize + 3; // to have 258m we need 259 samples
|
||||||
int heightmapHeightSamples = (int)regionsize + 2;
|
int heightmapHeightSamples = (int)regionsize + 3;
|
||||||
|
|
||||||
// Array of height samples for ODE
|
// Array of height samples for ODE
|
||||||
float[] _heightmap;
|
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
|
// Other ODE parameters
|
||||||
const float scale = 1.0f;
|
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 releasePinned();
|
||||||
void Append(IMesh newMesh);
|
void Append(IMesh newMesh);
|
||||||
void TransformLinear(float[,] matrix, float[] offset);
|
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>
|
/// <summary>
|
||||||
/// Used to pass collision information to OnCollisionUpdate listeners.
|
/// Used to pass collision information to OnCollisionUpdate listeners.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -135,6 +146,8 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event CollisionUpdate OnCollisionUpdate;
|
public event CollisionUpdate OnCollisionUpdate;
|
||||||
|
|
||||||
|
public virtual void SetVehicle(object vdata) { }
|
||||||
|
|
||||||
public event OutOfBounds OnOutOfBounds;
|
public event OutOfBounds OnOutOfBounds;
|
||||||
#pragma warning restore 67
|
#pragma warning restore 67
|
||||||
|
|
||||||
|
@ -142,6 +155,13 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
get { return new NullPhysicsActor(); }
|
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; }
|
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)
|
public virtual void RaiseOutOfBounds(Vector3 pos)
|
||||||
{
|
{
|
||||||
// Make a temporary copy of the event to avoid possibility of
|
// Make a temporary copy of the event to avoid possibility of
|
||||||
|
@ -554,5 +579,6 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,12 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||||
Vector3 size, Quaternion rotation, bool isPhysical, uint localid);
|
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
|
public virtual float TimeDilation
|
||||||
{
|
{
|
||||||
get { return 1.0f; }
|
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 Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {}
|
||||||
|
public virtual void CombineTerrain(float[] heightMap, Vector3 pOffset) {}
|
||||||
public virtual void UnCombine(PhysicsScene pScene) {}
|
public virtual void UnCombine(PhysicsScene pScene) {}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -263,5 +269,13 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
return new List<ContactResult>();
|
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 System;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.Manager
|
namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
|
@ -117,5 +118,47 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
NO_DEFLECTION = 16392,
|
NO_DEFLECTION = 16392,
|
||||||
LOCK_ROTATION = 32784
|
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;
|
IntPtr m_indicesPtr = IntPtr.Zero;
|
||||||
int m_indexCount = 0;
|
int m_indexCount = 0;
|
||||||
public float[] m_normals;
|
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()
|
public Mesh()
|
||||||
{
|
{
|
||||||
m_vertices = new Dictionary<Vertex, int>();
|
vertexcomp vcomp = new vertexcomp();
|
||||||
|
|
||||||
|
m_vertices = new Dictionary<Vertex, int>(vcomp);
|
||||||
m_triangles = new List<Triangle>();
|
m_triangles = new List<Triangle>();
|
||||||
|
_centroid = Vector3.Zero;
|
||||||
|
_centroidDiv = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mesh Clone()
|
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.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
|
||||||
}
|
}
|
||||||
|
result._centroid = _centroid;
|
||||||
|
result._centroidDiv = _centroidDiv;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,15 +97,57 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
||||||
// If a vertex of the triangle is not yet in the vertices list,
|
// If a vertex of the triangle is not yet in the vertices list,
|
||||||
// add it and set its index to the current index count
|
// 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))
|
if (!m_vertices.ContainsKey(triangle.v1))
|
||||||
|
{
|
||||||
m_vertices[triangle.v1] = m_vertices.Count;
|
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))
|
if (!m_vertices.ContainsKey(triangle.v2))
|
||||||
|
{
|
||||||
m_vertices[triangle.v2] = m_vertices.Count;
|
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))
|
if (!m_vertices.ContainsKey(triangle.v3))
|
||||||
|
{
|
||||||
m_vertices[triangle.v3] = m_vertices.Count;
|
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);
|
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()
|
public void CalcNormals()
|
||||||
{
|
{
|
||||||
int iTriangles = m_triangles.Count;
|
int iTriangles = m_triangles.Count;
|
||||||
|
|
|
@ -74,6 +74,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private bool cacheSculptMaps = true;
|
private bool cacheSculptMaps = true;
|
||||||
|
private bool cacheSculptAlphaMaps = true;
|
||||||
|
|
||||||
private string decodedSculptMapPath = null;
|
private string decodedSculptMapPath = null;
|
||||||
private bool useMeshiesPhysicsMesh = false;
|
private bool useMeshiesPhysicsMesh = false;
|
||||||
|
|
||||||
|
@ -87,7 +89,16 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
IConfig mesh_config = config.Configs["Mesh"];
|
IConfig mesh_config = config.Configs["Mesh"];
|
||||||
|
|
||||||
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
||||||
|
|
||||||
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
||||||
|
|
||||||
|
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||||
|
{
|
||||||
|
cacheSculptAlphaMaps = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cacheSculptAlphaMaps = cacheSculptMaps;
|
||||||
|
|
||||||
if(mesh_config != null)
|
if(mesh_config != null)
|
||||||
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
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))
|
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
|
||||||
return null;
|
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
|
else
|
||||||
{
|
{
|
||||||
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
|
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// keep compatible
|
||||||
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
|
|
||||||
primShape.SculptData = Utils.EmptyBytes;
|
primShape.SculptData = Utils.EmptyBytes;
|
||||||
|
|
||||||
int numCoords = coords.Count;
|
int numCoords = coords.Count;
|
||||||
|
@ -482,7 +496,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
|
//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); }
|
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
|
||||||
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
|
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)
|
if (bmW == 0 || bmH == 0)
|
||||||
throw new Exception("SculptMap: bitmap has no data");
|
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 needsScaling = false;
|
||||||
|
|
||||||
bool smallMap = bmW * bmH <= lod * lod;
|
|
||||||
|
|
||||||
width = bmW;
|
width = bmW;
|
||||||
height = bmH;
|
height = bmH;
|
||||||
while (width * height > numLodPixels)
|
while (width * height > numLodPixels * 4)
|
||||||
{
|
{
|
||||||
width >>= 1;
|
width >>= 1;
|
||||||
height >>= 1;
|
height >>= 1;
|
||||||
needsScaling = true;
|
needsScaling = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (needsScaling)
|
if (needsScaling)
|
||||||
bm = ScaleImage(bm, width, height,
|
bm = ScaleImage(bm, width, height);
|
||||||
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -87,7 +83,7 @@ namespace PrimMesher
|
||||||
throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
|
throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width * height > lod * lod)
|
if (width * height > numLodPixels)
|
||||||
{
|
{
|
||||||
width >>= 1;
|
width >>= 1;
|
||||||
height >>= 1;
|
height >>= 1;
|
||||||
|
@ -144,15 +140,17 @@ namespace PrimMesher
|
||||||
int rowNdx, colNdx;
|
int rowNdx, colNdx;
|
||||||
int smNdx = 0;
|
int smNdx = 0;
|
||||||
|
|
||||||
|
|
||||||
for (rowNdx = 0; rowNdx < numRows; rowNdx++)
|
for (rowNdx = 0; rowNdx < numRows; rowNdx++)
|
||||||
{
|
{
|
||||||
List<Coord> row = new List<Coord>(numCols);
|
List<Coord> row = new List<Coord>(numCols);
|
||||||
for (colNdx = 0; colNdx < numCols; colNdx++)
|
for (colNdx = 0; colNdx < numCols; colNdx++)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (mirror)
|
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
|
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;
|
++smNdx;
|
||||||
}
|
}
|
||||||
|
@ -161,23 +159,39 @@ namespace PrimMesher
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight,
|
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
|
||||||
System.Drawing.Drawing2D.InterpolationMode interpMode)
|
|
||||||
{
|
{
|
||||||
Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
|
|
||||||
scaledImage.SetResolution(96.0f, 96.0f);
|
|
||||||
|
|
||||||
Graphics grPhoto = Graphics.FromImage(scaledImage);
|
Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
|
||||||
grPhoto.InterpolationMode = interpMode;
|
|
||||||
|
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,
|
sx += xscale;
|
||||||
new Rectangle(0, 0, destWidth, destHeight),
|
}
|
||||||
new Rectangle(0, 0, srcImage.Width, srcImage.Height),
|
sy += yscale;
|
||||||
GraphicsUnit.Pixel);
|
}
|
||||||
|
srcImage.Dispose();
|
||||||
grPhoto.Dispose();
|
|
||||||
return scaledImage;
|
return scaledImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#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>
|
<CompilerDefines>TRACE;DEBUG</CompilerDefines>
|
||||||
<OptimizeCode>false</OptimizeCode>
|
<OptimizeCode>false</OptimizeCode>
|
||||||
<CheckUnderflowOverflow>false</CheckUnderflowOverflow>
|
<CheckUnderflowOverflow>false</CheckUnderflowOverflow>
|
||||||
<AllowUnsafe>false</AllowUnsafe>
|
<AllowUnsafe>true</AllowUnsafe>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<WarningsAsErrors>false</WarningsAsErrors>
|
<WarningsAsErrors>false</WarningsAsErrors>
|
||||||
<SuppressWarnings/>
|
<SuppressWarnings/>
|
||||||
|
@ -606,6 +606,36 @@
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</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">
|
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library">
|
||||||
<Configuration name="Debug">
|
<Configuration name="Debug">
|
||||||
<Options>
|
<Options>
|
||||||
|
@ -3316,16 +3346,12 @@
|
||||||
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
|
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
|
||||||
<Reference name="XMLRPC" path="../../../bin/"/>
|
<Reference name="XMLRPC" path="../../../bin/"/>
|
||||||
<Reference name="OpenSim.Framework"/>
|
<Reference name="OpenSim.Framework"/>
|
||||||
<Reference name="OpenSim.Framework.Communications"/>
|
|
||||||
<Reference name="OpenSim.Framework.Console"/>
|
<Reference name="OpenSim.Framework.Console"/>
|
||||||
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
|
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
|
||||||
<Reference name="OpenSim.Region.CoreModules"/>
|
<Reference name="OpenSim.Region.CoreModules"/>
|
||||||
<Reference name="OpenSim.Region.Framework"/>
|
<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.Region.ScriptEngine.XEngine"/>
|
||||||
<Reference name="OpenSim.Services.Interfaces"/>
|
<Reference name="OpenSim.Region.ScriptEngine.Shared"/>
|
||||||
<Reference name="OpenSim.Services.AvatarService"/>
|
|
||||||
<Reference name="OpenSim.Tests.Common"/>
|
<Reference name="OpenSim.Tests.Common"/>
|
||||||
<Files>
|
<Files>
|
||||||
<Match pattern="*.cs" recurse="false"/>
|
<Match pattern="*.cs" recurse="false"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
bin\Prebuild.exe /target nant
|
bin\Prebuild.exe /target nant
|
||||||
bin\Prebuild.exe /target vs2008
|
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