BulletSim: first unit test: vehicle angular attraction

user_profiles
Robert Adams 2013-01-28 17:08:34 -08:00
parent e9aff0a91d
commit 531d0429d1
6 changed files with 152 additions and 79 deletions

View File

@ -125,9 +125,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
static readonly float PIOverTwo = ((float)Math.PI) / 2f;
// For debugging, flags to turn on and off individual corrections.
private bool enableAngularVerticalAttraction;
private bool enableAngularDeflection;
private bool enableAngularBanking;
public bool enableAngularVerticalAttraction;
public bool enableAngularDeflection;
public bool enableAngularBanking;
public BSDynamics(BSScene myScene, BSPrim myPrim)
{
@ -165,7 +165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
}
#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);
switch (pParam)
@ -677,13 +677,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private const int m_knownChangedWaterLevel = 1 << 9;
private const int m_knownChangedForwardVelocity = 1 <<10;
private void ForgetKnownVehicleProperties()
public void ForgetKnownVehicleProperties()
{
m_knownHas = 0;
m_knownChanged = 0;
}
// Push all the changed values back into the physics engine
private void PushKnownChanged()
public void PushKnownChanged()
{
if (m_knownChanged != 0)
{

View File

@ -73,7 +73,7 @@ public sealed class BSPrim : BSPhysObject
private bool _kinematic;
private float _buoyancy;
private BSDynamics _vehicle;
public BSDynamics VehicleController { get; private set; }
private BSVMotor _targetMotor;
private OMV.Vector3 _PIDTarget;
@ -107,7 +107,7 @@ public sealed class BSPrim : BSPhysObject
_friction = PhysicsScene.Params.defaultFriction;
_restitution = PhysicsScene.Params.defaultRestitution;
_vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness
VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
_mass = CalculateMass();
@ -512,7 +512,7 @@ public sealed class BSPrim : BSPhysObject
public override int VehicleType {
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 {
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
// Vehicle code changes the parameters for this vehicle type.
_vehicle.ProcessTypeChange(type);
VehicleController.ProcessTypeChange(type);
ActivateIfPhysical(false);
// 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);
PhysicsScene.AfterStep -= _vehicle.PostStep;
PhysicsScene.AfterStep -= VehicleController.PostStep;
}
else
{
RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step);
PhysicsScene.AfterStep += _vehicle.PostStep;
RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
PhysicsScene.AfterStep += VehicleController.PostStep;
}
});
}
@ -542,7 +542,7 @@ public sealed class BSPrim : BSPhysObject
{
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
{
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
VehicleController.ProcessFloatVehicleParam((Vehicle)param, value);
ActivateIfPhysical(false);
});
}
@ -550,7 +550,7 @@ public sealed class BSPrim : BSPhysObject
{
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
{
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
VehicleController.ProcessVectorVehicleParam((Vehicle)param, value);
ActivateIfPhysical(false);
});
}
@ -558,7 +558,7 @@ public sealed class BSPrim : BSPhysObject
{
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
{
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation);
ActivateIfPhysical(false);
});
}
@ -566,7 +566,7 @@ public sealed class BSPrim : BSPhysObject
{
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
// isVolumeDetect: other objects pass through but can generate collisions
// 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);
@ -759,7 +759,7 @@ public sealed class BSPrim : BSPhysObject
MakeDynamic(IsStatic);
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
_vehicle.Refresh();
VehicleController.Refresh();
// Arrange for collision events if the simulator wants them
EnableCollisions(SubscribedEvents());
@ -1601,7 +1601,7 @@ public sealed class BSPrim : BSPhysObject
// Remove all the physical dependencies on the old body.
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
Linkset.RemoveBodyDependencies(this);
_vehicle.RemoveBodyDependencies(this);
VehicleController.RemoveBodyDependencies(this);
});
// 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
// TODO: handle physics introduced by Bullet with computed vehicle physics.
if (_vehicle.IsActive)
if (VehicleController.IsActive)
{
entprop.RotationalVelocity = OMV.Vector3.Zero;
}

View File

@ -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);
m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
Util.PrintCallStack(DetailLog);
// Util.PrintCallStack(DetailLog);
}
return InTaintTime;
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -33,8 +33,13 @@ using System.Text;
using NUnit.Framework;
using log4net;
using OpenSim.Framework;
using OpenSim.Region.Physics.BulletSPlugin;
using OpenSim.Region.Physics.Manager;
using OpenSim.Tests.Common;
using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin.Tests
{
[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 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]
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]
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));
}
}
}

View File

@ -47,7 +47,7 @@ public static class BulletSimTestsUtil
public static BSScene CreateBasicPhysicsEngine(Dictionary<string,string> paramOverrides)
{
IConfigSource openSimINI = new IniConfigSource();
IConfig startupConfig = openSimINI.AddConfig("StartUp");
IConfig startupConfig = openSimINI.AddConfig("Startup");
startupConfig.Set("physics", "BulletSim");
startupConfig.Set("meshing", "Meshmerizer");
startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps

View File

@ -3378,6 +3378,8 @@
<Reference name="Nini" path="../../../../../bin/"/>
<Reference name="log4net" 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.Tests.Common"/>
<Reference name="OpenSim.Region.CoreModules"/>