BulletSim: first unit test: vehicle angular attraction
parent
e9aff0a91d
commit
531d0429d1
|
@ -125,9 +125,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
static readonly float PIOverTwo = ((float)Math.PI) / 2f;
|
static readonly float PIOverTwo = ((float)Math.PI) / 2f;
|
||||||
|
|
||||||
// For debugging, flags to turn on and off individual corrections.
|
// For debugging, flags to turn on and off individual corrections.
|
||||||
private bool enableAngularVerticalAttraction;
|
public bool enableAngularVerticalAttraction;
|
||||||
private bool enableAngularDeflection;
|
public bool enableAngularDeflection;
|
||||||
private bool enableAngularBanking;
|
public bool enableAngularBanking;
|
||||||
|
|
||||||
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Vehicle parameter setting
|
#region Vehicle parameter setting
|
||||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||||
{
|
{
|
||||||
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
|
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
|
||||||
switch (pParam)
|
switch (pParam)
|
||||||
|
@ -677,13 +677,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
private const int m_knownChangedWaterLevel = 1 << 9;
|
private const int m_knownChangedWaterLevel = 1 << 9;
|
||||||
private const int m_knownChangedForwardVelocity = 1 <<10;
|
private const int m_knownChangedForwardVelocity = 1 <<10;
|
||||||
|
|
||||||
private void ForgetKnownVehicleProperties()
|
public void ForgetKnownVehicleProperties()
|
||||||
{
|
{
|
||||||
m_knownHas = 0;
|
m_knownHas = 0;
|
||||||
m_knownChanged = 0;
|
m_knownChanged = 0;
|
||||||
}
|
}
|
||||||
// Push all the changed values back into the physics engine
|
// Push all the changed values back into the physics engine
|
||||||
private void PushKnownChanged()
|
public void PushKnownChanged()
|
||||||
{
|
{
|
||||||
if (m_knownChanged != 0)
|
if (m_knownChanged != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,7 +73,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
private bool _kinematic;
|
private bool _kinematic;
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
private BSDynamics _vehicle;
|
public BSDynamics VehicleController { get; private set; }
|
||||||
|
|
||||||
private BSVMotor _targetMotor;
|
private BSVMotor _targetMotor;
|
||||||
private OMV.Vector3 _PIDTarget;
|
private OMV.Vector3 _PIDTarget;
|
||||||
|
@ -107,7 +107,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
_friction = PhysicsScene.Params.defaultFriction;
|
_friction = PhysicsScene.Params.defaultFriction;
|
||||||
_restitution = PhysicsScene.Params.defaultRestitution;
|
_restitution = PhysicsScene.Params.defaultRestitution;
|
||||||
|
|
||||||
_vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness
|
VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
|
||||||
|
|
||||||
_mass = CalculateMass();
|
_mass = CalculateMass();
|
||||||
|
|
||||||
|
@ -512,7 +512,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
public override int VehicleType {
|
public override int VehicleType {
|
||||||
get {
|
get {
|
||||||
return (int)_vehicle.Type; // if we are a vehicle, return that type
|
return (int)VehicleController.Type; // if we are a vehicle, return that type
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
Vehicle type = (Vehicle)value;
|
Vehicle type = (Vehicle)value;
|
||||||
|
@ -521,19 +521,19 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
// Done at taint time so we're sure the physics engine is not using the variables
|
// Done at taint time so we're sure the physics engine is not using the variables
|
||||||
// Vehicle code changes the parameters for this vehicle type.
|
// Vehicle code changes the parameters for this vehicle type.
|
||||||
_vehicle.ProcessTypeChange(type);
|
VehicleController.ProcessTypeChange(type);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
|
|
||||||
// If an active vehicle, register the vehicle code to be called before each step
|
// If an active vehicle, register the vehicle code to be called before each step
|
||||||
if (_vehicle.Type == Vehicle.TYPE_NONE)
|
if (VehicleController.Type == Vehicle.TYPE_NONE)
|
||||||
{
|
{
|
||||||
UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
|
UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
|
||||||
PhysicsScene.AfterStep -= _vehicle.PostStep;
|
PhysicsScene.AfterStep -= VehicleController.PostStep;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step);
|
RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
|
||||||
PhysicsScene.AfterStep += _vehicle.PostStep;
|
PhysicsScene.AfterStep += VehicleController.PostStep;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -542,7 +542,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
VehicleController.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -550,7 +550,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
VehicleController.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -558,7 +558,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -566,7 +566,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessVehicleFlags(param, remove);
|
VehicleController.ProcessVehicleFlags(param, remove);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +747,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// isSolid: other objects bounce off of this object
|
// isSolid: other objects bounce off of this object
|
||||||
// isVolumeDetect: other objects pass through but can generate collisions
|
// isVolumeDetect: other objects pass through but can generate collisions
|
||||||
// collisionEvents: whether this object returns collision events
|
// collisionEvents: whether this object returns collision events
|
||||||
private void UpdatePhysicalParameters()
|
public void UpdatePhysicalParameters()
|
||||||
{
|
{
|
||||||
// DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
|
// DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
|
||||||
|
|
||||||
|
@ -759,7 +759,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
MakeDynamic(IsStatic);
|
MakeDynamic(IsStatic);
|
||||||
|
|
||||||
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
|
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
|
||||||
_vehicle.Refresh();
|
VehicleController.Refresh();
|
||||||
|
|
||||||
// Arrange for collision events if the simulator wants them
|
// Arrange for collision events if the simulator wants them
|
||||||
EnableCollisions(SubscribedEvents());
|
EnableCollisions(SubscribedEvents());
|
||||||
|
@ -1601,7 +1601,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Remove all the physical dependencies on the old body.
|
// Remove all the physical dependencies on the old body.
|
||||||
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
|
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
|
||||||
Linkset.RemoveBodyDependencies(this);
|
Linkset.RemoveBodyDependencies(this);
|
||||||
_vehicle.RemoveBodyDependencies(this);
|
VehicleController.RemoveBodyDependencies(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Make sure the properties are set on the new object
|
// Make sure the properties are set on the new object
|
||||||
|
@ -1618,7 +1618,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
|
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
|
||||||
// TODO: handle physics introduced by Bullet with computed vehicle physics.
|
// TODO: handle physics introduced by Bullet with computed vehicle physics.
|
||||||
if (_vehicle.IsActive)
|
if (VehicleController.IsActive)
|
||||||
{
|
{
|
||||||
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
||||||
}
|
}
|
||||||
|
|
|
@ -855,7 +855,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
|
DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
|
||||||
m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
|
m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
|
||||||
Util.PrintCallStack(DetailLog);
|
// Util.PrintCallStack(DetailLog);
|
||||||
}
|
}
|
||||||
return InTaintTime;
|
return InTaintTime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -33,8 +33,13 @@ using System.Text;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.BulletSPlugin;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
using OpenSim.Tests.Common;
|
using OpenSim.Tests.Common;
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin.Tests
|
namespace OpenSim.Region.Physics.BulletSPlugin.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
@ -43,14 +48,80 @@ public class BasicVehicles : OpenSimTestCase
|
||||||
// Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
|
// Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
|
||||||
// Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
|
// Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
|
||||||
|
|
||||||
|
BSScene PhysicsScene { get; set; }
|
||||||
|
BSPrim TestVehicle { get; set; }
|
||||||
|
Vector3 TestVehicleInitPosition { get; set; }
|
||||||
|
float timeStep = 0.089f;
|
||||||
|
|
||||||
[TestFixtureSetUp]
|
[TestFixtureSetUp]
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
|
Dictionary<string, string> engineParams = new Dictionary<string, string>();
|
||||||
|
PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
|
||||||
|
|
||||||
|
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
|
||||||
|
Vector3 pos = new Vector3(100.0f, 100.0f, 0f);
|
||||||
|
pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2f;
|
||||||
|
TestVehicleInitPosition = pos;
|
||||||
|
Vector3 size = new Vector3(1f, 1f, 1f);
|
||||||
|
pbs.Scale = size;
|
||||||
|
Quaternion rot = Quaternion.Identity;
|
||||||
|
bool isPhys = false;
|
||||||
|
uint localID = 123;
|
||||||
|
|
||||||
|
PhysicsScene.AddPrimShape("testPrim", pbs, pos, size, rot, isPhys, localID);
|
||||||
|
TestVehicle = (BSPrim)PhysicsScene.PhysObjects[localID];
|
||||||
|
// The actual prim shape creation happens at taint time
|
||||||
|
PhysicsScene.ProcessTaints();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestFixtureTearDown]
|
[TestFixtureTearDown]
|
||||||
public void TearDown()
|
public void TearDown()
|
||||||
{
|
{
|
||||||
|
if (PhysicsScene != null)
|
||||||
|
{
|
||||||
|
// The Dispose() will also free any physical objects in the scene
|
||||||
|
PhysicsScene.Dispose();
|
||||||
|
PhysicsScene = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(25, 0.25f, 0.25f, 0.25f)]
|
||||||
|
[TestCase(25, -0.25f, 0.25f, 0.25f)]
|
||||||
|
[TestCase(25, 0.25f, -0.25f, 0.25f)]
|
||||||
|
[TestCase(25, -0.25f, -0.25f, 0.25f)]
|
||||||
|
public void VerticalAttraction(int simSteps, float initRoll, float initPitch, float initYaw)
|
||||||
|
{
|
||||||
|
Quaternion initOrientation = Quaternion.CreateFromEulers(initRoll, initPitch, initYaw);
|
||||||
|
TestVehicle.Orientation = initOrientation;
|
||||||
|
|
||||||
|
TestVehicle.Position = TestVehicleInitPosition;
|
||||||
|
|
||||||
|
// The vehicle controller is not enabled directly (set a vehicle type).
|
||||||
|
// Instead the appropriate values are set and calls are made just the parts of the
|
||||||
|
// controller we want to exercise. Stepping the physics engine then applies
|
||||||
|
// the actions of that one feature.
|
||||||
|
TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, 0.2f);
|
||||||
|
TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, 2f);
|
||||||
|
TestVehicle.VehicleController.enableAngularVerticalAttraction = true;
|
||||||
|
|
||||||
|
TestVehicle.IsPhysical = true;
|
||||||
|
PhysicsScene.ProcessTaints();
|
||||||
|
|
||||||
|
// Step the simulator a bunch of times and and vertical attraction should orient the vehicle up
|
||||||
|
for (int ii = 0; ii < simSteps; ii++)
|
||||||
|
{
|
||||||
|
TestVehicle.VehicleController.ForgetKnownVehicleProperties();
|
||||||
|
TestVehicle.VehicleController.ComputeAngularVerticalAttraction();
|
||||||
|
TestVehicle.VehicleController.PushKnownChanged();
|
||||||
|
|
||||||
|
PhysicsScene.Simulate(timeStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
// After these steps, the vehicle should be upright
|
||||||
|
Vector3 upPointer = Vector3.UnitZ * TestVehicle.Orientation;
|
||||||
|
Assert.That(upPointer.Z, Is.GreaterThan(0.99f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -47,7 +47,7 @@ public static class BulletSimTestsUtil
|
||||||
public static BSScene CreateBasicPhysicsEngine(Dictionary<string,string> paramOverrides)
|
public static BSScene CreateBasicPhysicsEngine(Dictionary<string,string> paramOverrides)
|
||||||
{
|
{
|
||||||
IConfigSource openSimINI = new IniConfigSource();
|
IConfigSource openSimINI = new IniConfigSource();
|
||||||
IConfig startupConfig = openSimINI.AddConfig("StartUp");
|
IConfig startupConfig = openSimINI.AddConfig("Startup");
|
||||||
startupConfig.Set("physics", "BulletSim");
|
startupConfig.Set("physics", "BulletSim");
|
||||||
startupConfig.Set("meshing", "Meshmerizer");
|
startupConfig.Set("meshing", "Meshmerizer");
|
||||||
startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps
|
startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps
|
||||||
|
|
|
@ -3378,6 +3378,8 @@
|
||||||
<Reference name="Nini" path="../../../../../bin/"/>
|
<Reference name="Nini" path="../../../../../bin/"/>
|
||||||
<Reference name="log4net" path="../../../../../bin/"/>
|
<Reference name="log4net" path="../../../../../bin/"/>
|
||||||
<Reference name="nunit.framework" path="../../../../../bin/"/>
|
<Reference name="nunit.framework" path="../../../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverse" path="../../../../../bin/"/>
|
||||||
|
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
|
||||||
<Reference name="OpenSim.Framework"/>
|
<Reference name="OpenSim.Framework"/>
|
||||||
<Reference name="OpenSim.Tests.Common"/>
|
<Reference name="OpenSim.Tests.Common"/>
|
||||||
<Reference name="OpenSim.Region.CoreModules"/>
|
<Reference name="OpenSim.Region.CoreModules"/>
|
||||||
|
|
Loading…
Reference in New Issue