Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
avinationmerge
Melanie 2012-12-18 09:44:10 +00:00
commit b9939a46a1
12 changed files with 217 additions and 131 deletions

View File

@ -1866,6 +1866,12 @@ namespace OpenSim.Framework
/// Prints the call stack at any given point. Useful for debugging.
/// </summary>
public static void PrintCallStack()
{
PrintCallStack(m_log.DebugFormat);
}
public delegate void DebugPrinter(string msg, params Object[] parm);
public static void PrintCallStack(DebugPrinter printer)
{
StackTrace stackTrace = new StackTrace(true); // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
@ -1874,7 +1880,7 @@ namespace OpenSim.Framework
foreach (StackFrame stackFrame in stackFrames)
{
MethodBase mb = stackFrame.GetMethod();
m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
printer("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
}
}

View File

@ -505,11 +505,19 @@ namespace OpenSim.Region.Framework.Scenes
if (Scene != null)
{
// if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
// || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
// && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
if ((Scene.TestBorderCross(val, Cardinals.E) || Scene.TestBorderCross(val, Cardinals.W)
|| Scene.TestBorderCross(val, Cardinals.N) || Scene.TestBorderCross(val, Cardinals.S))
if (
// (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E)
// || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
// || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N)
// || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
// Experimental change for better border crossings.
// The commented out original lines above would, it seems, trigger
// a border crossing a little early or late depending on which
// direction the object was moving.
(Scene.TestBorderCross(val, Cardinals.E)
|| Scene.TestBorderCross(val, Cardinals.W)
|| Scene.TestBorderCross(val, Cardinals.N)
|| Scene.TestBorderCross(val, Cardinals.S))
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
{
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();

View File

@ -311,6 +311,15 @@ public sealed class BSCharacter : BSPhysObject
{
bool ret = false;
// TODO: check for out of bounds
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
{
// The character is out of the known/simulated area.
// Upper levels of code will handle the transition to other areas so, for
// the time, we just ignore the position.
return ret;
}
// If below the ground, move the avatar up
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
if (Position.Z < terrainHeight)
@ -329,7 +338,6 @@ public sealed class BSCharacter : BSPhysObject
}
}
// TODO: check for out of bounds
return ret;
}
@ -700,7 +708,7 @@ public sealed class BSCharacter : BSPhysObject
}
// Tell the linkset about value changes
Linkset.UpdateProperties(this);
Linkset.UpdateProperties(this, true);
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
// base.RequestPhysicsterseUpdate();

View File

@ -871,8 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (VehiclePosition.Z < GetTerrainHeight(VehiclePosition))
{
// TODO: correct position by applying force rather than forcing position.
VehiclePosition += new Vector3(0f, 0f, GetTerrainHeight(VehiclePosition) + 2f);
VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
Vector3 newPosition = VehiclePosition;
newPosition.Z = GetTerrainHeight(VehiclePosition) + 1f;
VehiclePosition = newPosition;
VDetailLog("{0}, MoveLinear,terrainHeight,terrainHeight={1},pos={2}",
Prim.LocalID, GetTerrainHeight(VehiclePosition), VehiclePosition);
}
return ret;
}

View File

@ -38,6 +38,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Each type of linkset will define the information needed for its type.
public abstract class BSLinksetInfo
{
public virtual void Clear() { }
}
public abstract class BSLinkset
@ -95,13 +96,6 @@ public abstract class BSLinkset
return BSPhysicsShapeType.SHAPE_UNKNOWN;
}
// Linksets move around the children so the linkset might need to compute the child position
public virtual OMV.Vector3 Position(BSPhysObject member)
{ return member.RawPosition; }
public virtual OMV.Quaternion Orientation(BSPhysObject member)
{ return member.RawOrientation; }
// TODO: does this need to be done for Velocity and RotationalVelocityy?
// We keep the prim's mass in the linkset structure since it could be dependent on other prims
protected float m_mass;
public float LinksetMass
@ -258,8 +252,9 @@ public abstract class BSLinkset
// Called when a parameter update comes from the physics engine for any object
// of the linkset is received.
// Passed flag is update came from physics engine (true) or the user (false).
// Called at taint-time!!
public abstract void UpdateProperties(BSPhysObject physObject);
public abstract void UpdateProperties(BSPhysObject physObject, bool physicalUpdate);
// Routine used when rebuilding the body of the root of the linkset
// Destroy all the constraints have have been made to root.

View File

@ -28,6 +28,8 @@ using System;
using System.Collections.Generic;
using System.Text;
using OpenSim.Framework;
using OMV = OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
@ -45,6 +47,11 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo
OffsetPos = p;
OffsetRot = r;
}
public override void Clear()
{
OffsetPos = OMV.Vector3.Zero;
OffsetRot = OMV.Quaternion.Identity;
}
public override string ToString()
{
StringBuilder buff = new StringBuilder();
@ -82,22 +89,22 @@ public sealed class BSLinksetCompound : BSLinkset
// its internal properties.
public override void Refresh(BSPhysObject requestor)
{
// External request for Refresh (from BSPrim) doesn't need to do anything
// InternalRefresh(requestor);
// Something changed so do the rebuilding thing
// ScheduleRebuild();
}
// Schedule a refresh to happen after all the other taint processing.
private void InternalRefresh(BSPhysObject requestor)
private void ScheduleRebuild()
{
DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1},rebuilding={2}",
LinksetRoot.LocalID, requestor.LocalID, Rebuilding);
DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,rebuilding={1}",
LinksetRoot.LocalID, Rebuilding);
// When rebuilding, it is possible to set properties that would normally require a rebuild.
// If already rebuilding, don't request another rebuild.
if (!Rebuilding)
{
PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate()
PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", LinksetRoot.LocalID, delegate()
{
if (IsRoot(requestor) && HasAnyChildren)
if (HasAnyChildren)
RecomputeLinksetCompound();
});
}
@ -117,8 +124,7 @@ public sealed class BSLinksetCompound : BSLinkset
{
// The root is going dynamic. Make sure mass is properly set.
m_mass = ComputeLinksetMass();
if (HasAnyChildren)
InternalRefresh(LinksetRoot);
ScheduleRebuild();
}
else
{
@ -147,8 +153,7 @@ public sealed class BSLinksetCompound : BSLinkset
DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
if (IsRoot(child))
{
if (HasAnyChildren)
InternalRefresh(LinksetRoot);
ScheduleRebuild();
}
else
{
@ -164,22 +169,21 @@ public sealed class BSLinksetCompound : BSLinkset
return ret;
}
// Called at taint-time!!
public override void UpdateProperties(BSPhysObject updated)
public override void UpdateProperties(BSPhysObject updated, bool physicalUpdate)
{
// Nothing to do for compound linksets on property updates
}
// The children move around in relationship to the root.
// Just grab the current values of wherever it is right now.
public override OMV.Vector3 Position(BSPhysObject member)
{
return BulletSimAPI.GetPosition2(member.PhysBody.ptr);
}
public override OMV.Quaternion Orientation(BSPhysObject member)
{
return BulletSimAPI.GetOrientation2(member.PhysBody.ptr);
// The user moving a child around requires the rebuilding of the linkset compound shape
// One problem is this happens when a border is crossed -- the simulator implementation
// is to store the position into the group which causes the move of the object
// but it also means all the child positions get updated.
// What would cause an unnecessary rebuild so we make sure the linkset is in a
// region before bothering to do a rebuild.
if (!IsRoot(updated)
&& !physicalUpdate
&& PhysicsScene.TerrainManager.IsWithinKnownTerrain(LinksetRoot.RawPosition))
{
updated.LinksetInfo = null;
ScheduleRebuild();
}
}
// Routine called when rebuilding the body of some member of the linkset.
@ -261,8 +265,8 @@ public sealed class BSLinksetCompound : BSLinkset
DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
// Cause constraints and assorted properties to be recomputed before the next simulation step.
InternalRefresh(LinksetRoot);
// Rebuild the compound shape with the new child shape included
ScheduleRebuild();
}
return;
}
@ -289,8 +293,8 @@ public sealed class BSLinksetCompound : BSLinkset
}
else
{
// Schedule a rebuild of the linkset before the next simulation tick.
InternalRefresh(LinksetRoot);
// Rebuild the compound shape with the child removed
ScheduleRebuild();
}
}
return;

View File

@ -78,23 +78,11 @@ public sealed class BSLinksetConstraints : BSLinkset
}
// Called at taint-time!!
public override void UpdateProperties(BSPhysObject updated)
public override void UpdateProperties(BSPhysObject updated, bool inTaintTime)
{
// Nothing to do for constraints on property updates
}
// The children of the linkset are moved around by the constraints.
// Just grab the current values of wherever it is right now.
public override OMV.Vector3 Position(BSPhysObject member)
{
return BulletSimAPI.GetPosition2(member.PhysBody.ptr);
}
public override OMV.Quaternion Orientation(BSPhysObject member)
{
return BulletSimAPI.GetOrientation2(member.PhysBody.ptr);
}
// Routine called when rebuilding the body of some member of the linkset.
// Destroy all the constraints have have been made to root and set
// up to rebuild the constraints before the next simulation step.

View File

@ -214,7 +214,7 @@ public abstract class BSPhysObject : PhysicsActor
{
bool ret = true;
// If the 'no collision' call, force it to happen right now so quick collision_end
bool force = CollisionCollection.Count == 0;
bool force = (CollisionCollection.Count == 0);
// throttle the collisions to the number of milliseconds specified in the subscription
if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime))
@ -232,8 +232,10 @@ public abstract class BSPhysObject : PhysicsActor
// DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
base.SendCollisionUpdate(CollisionCollection);
// The collisionCollection structure is passed around in the simulator.
// The CollisionCollection instance is passed around in the simulator.
// Make sure we don't have a handle to that one and that a new one is used for next time.
// This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,
// a race condition is created for the other users of this instance.
CollisionCollection = new CollisionEventUpdate();
}
return ret;
@ -251,7 +253,8 @@ public abstract class BSPhysObject : PhysicsActor
PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
{
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
if (PhysBody.HasPhysicalBody)
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
});
}
else

View File

@ -279,9 +279,12 @@ public sealed class BSPrim : BSPhysObject
}
public override OMV.Vector3 Position {
get {
/* NOTE: this refetch is not necessary. The simulator knows about linkset children
* and does not fetch this position info for children. Thus this is commented out.
// child prims move around based on their parent. Need to get the latest location
if (!Linkset.IsRoot(this))
_position = Linkset.Position(this);
_position = Linkset.PositionGet(this);
*/
// don't do the GetObjectPosition for root elements because this function is called a zillion times.
// _position = BulletSimAPI.GetObjectPosition2(PhysicsScene.World.ptr, BSBody.ptr);
@ -289,21 +292,22 @@ public sealed class BSPrim : BSPhysObject
}
set {
// If the position must be forced into the physics engine, use ForcePosition.
// All positions are given in world positions.
if (_position == value)
{
DetailLog("{0},BSPrim.setPosition,taint,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation);
return;
}
_position = value;
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
PositionSanityCheck(false);
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(this, false);
PhysicsScene.TaintedObject("BSPrim.setPosition", delegate()
{
// DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
ActivateIfPhysical(false);
}
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
ForcePosition = _position;
});
}
}
@ -314,9 +318,11 @@ public sealed class BSPrim : BSPhysObject
}
set {
_position = value;
// PositionSanityCheck(); // Don't do this! Causes a loop and caller should know better.
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
ActivateIfPhysical(false);
if (PhysBody.HasPhysicalBody)
{
BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
ActivateIfPhysical(false);
}
}
}
@ -327,6 +333,14 @@ public sealed class BSPrim : BSPhysObject
{
bool ret = false;
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position))
{
// The physical object is out of the known/simulated area.
// Upper levels of code will handle the transition to other areas so, for
// the time, we just ignore the position.
return ret;
}
float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position);
OMV.Vector3 upForce = OMV.Vector3.Zero;
if (RawPosition.Z < terrainHeight)
@ -350,8 +364,6 @@ public sealed class BSPrim : BSPhysObject
}
}
// TODO: check for out of bounds
// The above code computes a force to apply to correct any out-of-bounds problems. Apply same.
// TODO: This should be intergrated with a geneal physics action mechanism.
// TODO: This should be moderated with PID'ness.
@ -551,18 +563,24 @@ public sealed class BSPrim : BSPhysObject
}
public override OMV.Quaternion Orientation {
get {
/* NOTE: this refetch is not necessary. The simulator knows about linkset children
* and does not fetch this position info for children. Thus this is commented out.
// Children move around because tied to parent. Get a fresh value.
if (!Linkset.IsRoot(this))
{
_orientation = Linkset.Orientation(this);
_orientation = Linkset.OrientationGet(this);
}
*/
return _orientation;
}
set {
if (_orientation == value)
return;
_orientation = value;
// TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(this, false);
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
{
if (PhysBody.HasPhysicalBody)
@ -1427,14 +1445,14 @@ public sealed class BSPrim : BSPhysObject
entprop.Velocity = _velocity;
}
// remember the current and last set values
LastEntityProperties = CurrentEntityProperties;
CurrentEntityProperties = entprop;
OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},dir={3},vel={4},rotVel={5}",
LocalID, _position, _orientation, direction, _velocity, _rotationalVelocity);
// remember the current and last set values
LastEntityProperties = CurrentEntityProperties;
CurrentEntityProperties = entprop;
base.RequestPhysicsterseUpdate();
}
/*
@ -1448,7 +1466,7 @@ public sealed class BSPrim : BSPhysObject
*/
// The linkset implimentation might want to know about this.
Linkset.UpdateProperties(this);
Linkset.UpdateProperties(this, true);
}
}
}

View File

@ -349,8 +349,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// make sure no stepping happens while we're deleting stuff
m_initialized = false;
TerrainManager.ReleaseGroundPlaneAndTerrain();
foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
{
kvp.Value.Destroy();
@ -370,6 +368,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
Shapes = null;
}
if (TerrainManager != null)
{
TerrainManager.ReleaseGroundPlaneAndTerrain();
TerrainManager.Dispose();
TerrainManager = null;
}
// Anything left in the unmanaged code should be cleaned out
BulletSimAPI.Shutdown2(World.ptr);
@ -512,8 +517,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}",
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps,
updatedEntityCount, collidersCount, ObjectsWithCollisions.Count);
if (VehiclePhysicalLoggingEnabled) DumpVehicles(); // DEBUG
}
catch (Exception e)
@ -568,6 +574,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Objects that are done colliding are removed from the ObjectsWithCollisions list.
// Not done above because it is inside an iteration of ObjectWithCollisions.
// This complex collision processing is required to create an empty collision
// event call after all collisions have happened on an object. This enables
// the simulator to generate the 'collision end' event.
if (ObjectsWithNoMoreCollisions.Count > 0)
{
foreach (BSPhysObject po in ObjectsWithNoMoreCollisions)
@ -592,7 +601,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
ProcessPostStepTaints();
// This causes the unmanaged code to output ALL the values found in ALL the objects in the world.
// The following causes the unmanaged code to output ALL the values found in ALL the objects in the world.
// Only enable this in a limited test world with few objects.
// BulletSimAPI.DumpAllInfo2(World.ptr); // DEBUG DEBUG DEBUG

View File

@ -67,7 +67,7 @@ public abstract class BSTerrainPhys : IDisposable
}
// ==========================================================================================
public sealed class BSTerrainManager
public sealed class BSTerrainManager : IDisposable
{
static string LogHeader = "[BULLETSIM TERRAIN MANAGER]";
@ -122,6 +122,11 @@ public sealed class BSTerrainManager
MegaRegionParentPhysicsScene = null;
}
public void Dispose()
{
ReleaseGroundPlaneAndTerrain();
}
// Create the initial instance of terrain and the underlying ground plane.
// This is called from the initialization routine so we presume it is
// safe to call Bullet in real time. We hope no one is moving prims around yet.
@ -327,6 +332,13 @@ public sealed class BSTerrainManager
return newTerrainPhys;
}
// Return 'true' of this position is somewhere in known physical terrain space
public bool IsWithinKnownTerrain(Vector3 pos)
{
Vector3 terrainBaseXYZ;
BSTerrainPhys physTerrain;
return GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ);
}
// Given an X and Y, find the height of the terrain.
// Since we could be handling multiple terrains for a mega-region,
@ -337,13 +349,13 @@ public sealed class BSTerrainManager
private float lastHeightTX = 999999f;
private float lastHeightTY = 999999f;
private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
public float GetTerrainHeightAtXYZ(Vector3 loc)
public float GetTerrainHeightAtXYZ(Vector3 pos)
{
float tX = loc.X;
float tY = loc.Y;
float tX = pos.X;
float tY = pos.Y;
// You'd be surprized at the number of times this routine is called
// with the same parameters as last time.
if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
if (!m_terrainModified && (lastHeightTX == tX) && (lastHeightTY == tY))
return lastHeight;
m_terrainModified = false;
@ -351,23 +363,20 @@ public sealed class BSTerrainManager
lastHeightTY = tY;
float ret = HEIGHT_GETHEIGHT_RET;
int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
lock (m_terrains)
Vector3 terrainBaseXYZ;
BSTerrainPhys physTerrain;
if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ))
{
BSTerrainPhys physTerrain;
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
{
ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ);
}
else
{
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
LogHeader, PhysicsScene.RegionName, tX, tY);
}
ret = physTerrain.GetTerrainHeightAtXYZ(pos - terrainBaseXYZ);
}
else
{
PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
LogHeader, PhysicsScene.RegionName, tX, tY);
DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,terrainNotFound,pos={1},base={2}",
BSScene.DetailLogZero, pos, terrainBaseXYZ);
}
lastHeight = ret;
return ret;
}
@ -376,29 +385,38 @@ public sealed class BSTerrainManager
{
float ret = WATER_HEIGHT_GETHEIGHT_RET;
float tX = pos.X;
float tY = pos.Y;
Vector3 terrainBaseXYZ = Vector3.Zero;
terrainBaseXYZ.X = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
terrainBaseXYZ.Y = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
lock (m_terrains)
Vector3 terrainBaseXYZ;
BSTerrainPhys physTerrain;
if (GetTerrainPhysicalAtXYZ(pos, out physTerrain, out terrainBaseXYZ))
{
BSTerrainPhys physTerrain;
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
{
ret = physTerrain.GetWaterLevelAtXYZ(pos);
}
else
{
PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
LogHeader, PhysicsScene.RegionName, tX, tY);
}
ret = physTerrain.GetWaterLevelAtXYZ(pos);
}
else
{
PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: pos={1}, terrainBase={2}, height={3}",
LogHeader, PhysicsScene.RegionName, pos, terrainBaseXYZ, ret);
}
return ret;
}
// Given an address, return 'true' of there is a description of that terrain and output
// the descriptor class and the 'base' fo the addresses therein.
private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase)
{
int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);
BSTerrainPhys physTerrain = null;
lock (m_terrains)
{
m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain);
}
outTerrainBase = terrainBaseXYZ;
outPhysTerrain = physTerrain;
return (physTerrain != null);
}
// Although no one seems to check this, I do support combining.
public bool SupportsCombining()
{

View File

@ -1,3 +1,16 @@
CURRENT PRIORITIES
=================================================
Eliminate all crashes (DONEish)
Editing/deleting physical linkset (DONE)
Border crossing of physical linkset (DONE)
Enable vehicle border crossings (at least as poorly as ODE)
Avatar created in previous region and not new region when crossing border
Vehicle recreated in new sim at small Z value (offset from root value?)
Calibrate turning radius
limitMotorUp calibration (more down?)
study PID motors (include 'efficiency' implementation
Add to avatar movement
CRASHES
=================================================
20121129.1411: editting/moving phys object across region boundries causes crash
@ -11,16 +24,18 @@ CRASHES
VEHICLES TODO LIST:
=================================================
Border crossing with linked vehicle causes crash
Neb vehicle taking > 25ms of physics time!!
Vehicles (Move smoothly)
Add vehicle collisions so IsColliding is properly reported.
Needed for banking, limitMotorUp, movementLimiting, ...
Some vehicles should not be able to turn if no speed or off ground.
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
Neb car jiggling left and right
Happens on terrain and any other mesh object. Flat cubes are much smoother.
This has been reduced but not eliminated.
Light cycle falling over when driving
For limitMotorUp, use raycast down to find if vehicle is in the air.
Implement referenceFrame for all the motion routines.
Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
Verify that angular motion specified around Z moves in the vehicle coordinates.
Verify llGetVel() is returning a smooth and good value for vehicle movement.
@ -31,12 +46,13 @@ Should vehicle angular/linear movement friction happen after all the components
After getting off a vehicle, the root prim is phantom (can be walked through)
Need to force a position update for the root prim after compound shape destruction
Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint)
Implement referenceFrame for all the motion routines.
Cannot edit/move a vehicle being ridden: it jumps back to the origional position.
Border crossing with linked vehicle causes crash
For limitMotorUp, use raycast down to find if vehicle is in the air.
Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties().
A kludge that isn't fixing the real problem of Bullet adding extra motion.
BULLETSIM TODO LIST:
=================================================
Revisit CollisionMargin. Builders notice the 0.04 spacing between prims.
Avatar height off after unsitting (floats off ground)
Editting appearance then moving restores.
Must not be initializing height when recreating capsule after unsit.
@ -64,11 +80,16 @@ Implement ShapeCollection.Dispose()
Implement water as a plain so raycasting and collisions can happen with same.
Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE
Also osGetPhysicsEngineVerion() maybe.
Linkset.Position and Linkset.Orientation requre rewrite to properly return
child position. LinksetConstraint acts like it's at taint time!!
LINKSETS
======================================================
Linksets should allow collisions to individual children
Add LocalID to children shapes in LinksetCompound and create events for individuals
LinksetCompound: when one of the children changes orientation (like tires
turning on a vehicle, the whole compound object is rebuilt. Optimize this
so orientation/position of individual children can change without a rebuild.
Verify/think through scripts in children of linksets. What do they reference
and return when getting position, velocity, ...
Confirm constraint linksets still work after making all the changes for compound linksets.
@ -140,6 +161,11 @@ Remove HeightmapInfo from terrain specification
Since C++ code does not need terrain height, this structure et al are not needed.
Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will
bob at the water level. BSPrim.PositionSanityCheck().
Should taints check for existance or activeness of target?
When destroying linksets/etc, taints can be generated for objects that are
actually gone when the taint happens. Crashes don't happen because the taint closure
keeps the object from being freed, but that is just an accident.
Possibly have and 'active' flag that is checked by the taint processor?
THREADING
=================================================