BulletSim: Remove use of shapeData in ShapeCollection and rely on the available BSPhysObject varaiables. Fix line endings in BSLinksetCompound.
parent
364a7c3088
commit
39c02dcc8c
|
@ -99,26 +99,12 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||||
LocalID, _size, Scale, _avatarDensity, _avatarVolume, MassRaw);
|
LocalID, _size, Scale, _avatarDensity, _avatarVolume, MassRaw);
|
||||||
|
|
||||||
ShapeData shapeData = new ShapeData();
|
|
||||||
shapeData.ID = LocalID;
|
|
||||||
shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
|
|
||||||
shapeData.Position = _position;
|
|
||||||
shapeData.Rotation = _orientation;
|
|
||||||
shapeData.Velocity = _velocity;
|
|
||||||
shapeData.Size = Scale; // capsule is a native shape but scale is not just <1,1,1>
|
|
||||||
shapeData.Scale = Scale;
|
|
||||||
shapeData.Mass = _mass;
|
|
||||||
shapeData.Buoyancy = _buoyancy;
|
|
||||||
shapeData.Static = ShapeData.numericFalse;
|
|
||||||
shapeData.Friction = PhysicsScene.Params.avatarStandingFriction;
|
|
||||||
shapeData.Restitution = PhysicsScene.Params.avatarRestitution;
|
|
||||||
|
|
||||||
// do actual create at taint time
|
// do actual create at taint time
|
||||||
PhysicsScene.TaintedObject("BSCharacter.create", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.create", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.create,taint", LocalID);
|
DetailLog("{0},BSCharacter.create,taint", LocalID);
|
||||||
// New body and shape into BSBody and BSShape
|
// New body and shape into BSBody and BSShape
|
||||||
PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null);
|
PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, null, null);
|
||||||
|
|
||||||
SetPhysicalProperties();
|
SetPhysicalProperties();
|
||||||
});
|
});
|
||||||
|
@ -212,6 +198,9 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
{
|
{
|
||||||
set { BaseShape = value; }
|
set { BaseShape = value; }
|
||||||
}
|
}
|
||||||
|
// I want the physics engine to make an avatar capsule
|
||||||
|
public override ShapeData.PhysicsShapeType PreferredPhysicalShape
|
||||||
|
{ get { return ShapeData.PhysicsShapeType.SHAPE_AVATAR; } }
|
||||||
|
|
||||||
public override bool Grabbed {
|
public override bool Grabbed {
|
||||||
set { _grabbed = value; }
|
set { _grabbed = value; }
|
||||||
|
|
|
@ -68,6 +68,11 @@ public abstract class BSLinkset
|
||||||
// to the physical representation is done via the tainting mechenism.
|
// to the physical representation is done via the tainting mechenism.
|
||||||
protected object m_linksetActivityLock = new Object();
|
protected object m_linksetActivityLock = new Object();
|
||||||
|
|
||||||
|
// Some linksets have a preferred physical shape.
|
||||||
|
// Returns SHAPE_UNKNOWN if there is no preference.
|
||||||
|
public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape
|
||||||
|
{ get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } }
|
||||||
|
|
||||||
// We keep the prim's mass in the linkset structure since it could be dependent on other prims
|
// We keep the prim's mass in the linkset structure since it could be dependent on other prims
|
||||||
protected float m_mass;
|
protected float m_mass;
|
||||||
public float LinksetMass
|
public float LinksetMass
|
||||||
|
|
|
@ -1,173 +1,176 @@
|
||||||
/*
|
/*
|
||||||
* 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.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyrightD
|
* * Redistributions in binary form must reproduce the above copyrightD
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using OMV = OpenMetaverse;
|
using OMV = OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
public sealed class BSLinksetCompound : BSLinkset
|
public sealed class BSLinksetCompound : BSLinkset
|
||||||
{
|
{
|
||||||
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
|
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
|
||||||
|
|
||||||
public BSLinksetCompound(BSScene scene, BSPhysObject parent)
|
public BSLinksetCompound(BSScene scene, BSPhysObject parent)
|
||||||
{
|
{
|
||||||
base.Initialize(scene, parent);
|
base.Initialize(scene, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When physical properties are changed the linkset needs to recalculate
|
// When physical properties are changed the linkset needs to recalculate
|
||||||
// its internal properties.
|
// its internal properties.
|
||||||
// This is queued in the 'post taint' queue so the
|
// This is queued in the 'post taint' queue so the
|
||||||
// refresh will happen once after all the other taints are applied.
|
// refresh will happen once after all the other taints are applied.
|
||||||
public override void Refresh(BSPhysObject requestor)
|
public override void Refresh(BSPhysObject requestor)
|
||||||
{
|
{
|
||||||
// Queue to happen after all the other taint processing
|
// Queue to happen after all the other taint processing
|
||||||
PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate()
|
PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate()
|
||||||
{
|
{
|
||||||
if (HasAnyChildren && IsRoot(requestor))
|
if (HasAnyChildren && IsRoot(requestor))
|
||||||
RecomputeLinksetCompound();
|
RecomputeLinksetCompound();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// The object is going dynamic (physical). Do any setup necessary
|
// The object is going dynamic (physical). Do any setup necessary
|
||||||
// for a dynamic linkset.
|
// for a dynamic linkset.
|
||||||
// Only the state of the passed object can be modified. The rest of the linkset
|
// Only the state of the passed object can be modified. The rest of the linkset
|
||||||
// has not yet been fully constructed.
|
// has not yet been fully constructed.
|
||||||
// Return 'true' if any properties updated on the passed object.
|
// Return 'true' if any properties updated on the passed object.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public override bool MakeDynamic(BSPhysObject child)
|
public override bool MakeDynamic(BSPhysObject child)
|
||||||
{
|
{
|
||||||
// What is done for each object in BSPrim is what we want.
|
// What is done for each object in BSPrim is what we want.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The object is going static (non-physical). Do any setup necessary for a static linkset.
|
// The object is going static (non-physical). Do any setup necessary for a static linkset.
|
||||||
// Return 'true' if any properties updated on the passed object.
|
// Return 'true' if any properties updated on the passed object.
|
||||||
// This doesn't normally happen -- OpenSim removes the objects from the physical
|
// This doesn't normally happen -- OpenSim removes the objects from the physical
|
||||||
// world if it is a static linkset.
|
// world if it is a static linkset.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public override bool MakeStatic(BSPhysObject child)
|
public override bool MakeStatic(BSPhysObject child)
|
||||||
{
|
{
|
||||||
// What is done for each object in BSPrim is what we want.
|
// What is done for each object in BSPrim is what we want.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public override void UpdateProperties(BSPhysObject updated)
|
public override void UpdateProperties(BSPhysObject updated)
|
||||||
{
|
{
|
||||||
// Nothing to do for constraints on property updates
|
// Nothing to do for constraints on property updates
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routine called when rebuilding the body of some member of the linkset.
|
// Routine called when rebuilding the body of some member of the linkset.
|
||||||
// Destroy all the constraints have have been made to root and set
|
// Destroy all the constraints have have been made to root and set
|
||||||
// up to rebuild the constraints before the next simulation step.
|
// up to rebuild the constraints before the next simulation step.
|
||||||
// Returns 'true' of something was actually removed and would need restoring
|
// Returns 'true' of something was actually removed and would need restoring
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public override bool RemoveBodyDependencies(BSPrim child)
|
public override bool RemoveBodyDependencies(BSPrim child)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
|
DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}",
|
||||||
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"));
|
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"));
|
||||||
|
|
||||||
// Cause the current shape to be freed and the new one to be built.
|
// Cause the current shape to be freed and the new one to be built.
|
||||||
Refresh(LinksetRoot);
|
Refresh(LinksetRoot);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
|
// Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
|
||||||
// this routine will restore the removed constraints.
|
// this routine will restore the removed constraints.
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public override void RestoreBodyDependencies(BSPrim child)
|
public override void RestoreBodyDependencies(BSPrim child)
|
||||||
{
|
{
|
||||||
// The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints.
|
// The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints.
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
|
|
||||||
// Add a new child to the linkset.
|
// Add a new child to the linkset.
|
||||||
// Called while LinkActivity is locked.
|
// Called while LinkActivity is locked.
|
||||||
protected override void AddChildToLinkset(BSPhysObject child)
|
protected override void AddChildToLinkset(BSPhysObject child)
|
||||||
{
|
{
|
||||||
if (!HasChild(child))
|
if (!HasChild(child))
|
||||||
{
|
{
|
||||||
m_children.Add(child);
|
m_children.Add(child);
|
||||||
|
|
||||||
DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
|
DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
|
||||||
|
|
||||||
// Cause constraints and assorted properties to be recomputed before the next simulation step.
|
// Cause constraints and assorted properties to be recomputed before the next simulation step.
|
||||||
Refresh(LinksetRoot);
|
Refresh(LinksetRoot);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the specified child from the linkset.
|
// Remove the specified child from the linkset.
|
||||||
// Safe to call even if the child is not really in my linkset.
|
// Safe to call even if the child is not really in my linkset.
|
||||||
protected override void RemoveChildFromLinkset(BSPhysObject child)
|
protected override void RemoveChildFromLinkset(BSPhysObject child)
|
||||||
{
|
{
|
||||||
if (m_children.Remove(child))
|
if (m_children.Remove(child))
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
|
DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
|
||||||
child.LocalID,
|
child.LocalID,
|
||||||
LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"),
|
LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"),
|
||||||
child.LocalID, child.PhysBody.ptr.ToString("X"));
|
child.LocalID, child.PhysBody.ptr.ToString("X"));
|
||||||
|
|
||||||
// See that the linkset parameters are recomputed at the end of the taint time.
|
// See that the linkset parameters are recomputed at the end of the taint time.
|
||||||
Refresh(LinksetRoot);
|
Refresh(LinksetRoot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Non-fatal occurance.
|
// Non-fatal occurance.
|
||||||
// PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
|
// PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Call each of the constraints that make up this linkset and recompute the
|
// Call each of the constraints that make up this linkset and recompute the
|
||||||
// various transforms and variables. Create constraints of not created yet.
|
// various transforms and variables. Create constraints of not created yet.
|
||||||
// Called before the simulation step to make sure the constraint based linkset
|
// Called before the simulation step to make sure the constraint based linkset
|
||||||
// is all initialized.
|
// is all initialized.
|
||||||
// Called at taint time!!
|
// Called at taint time!!
|
||||||
private void RecomputeLinksetCompound()
|
private void RecomputeLinksetCompound()
|
||||||
{
|
{
|
||||||
float linksetMass = LinksetMass;
|
// Release the existing shape
|
||||||
LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
|
PhysicsScene.Shapes.DereferenceShape(LinksetRoot.PhysShape, true, null);
|
||||||
|
|
||||||
// DEBUG: see of inter-linkset collisions are causing problems
|
float linksetMass = LinksetMass;
|
||||||
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
|
LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
|
||||||
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
|
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}",
|
// DEBUG: see of inter-linkset collisions are causing problems
|
||||||
LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass);
|
// BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
|
||||||
|
// (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
|
||||||
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}",
|
||||||
}
|
LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass);
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -78,6 +78,10 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
|
|
||||||
// The objects base shape information. Null if not a prim type shape.
|
// The objects base shape information. Null if not a prim type shape.
|
||||||
public PrimitiveBaseShape BaseShape { get; protected set; }
|
public PrimitiveBaseShape BaseShape { get; protected set; }
|
||||||
|
// Some types of objects have preferred physical representations.
|
||||||
|
// Returns SHAPE_UNKNOWN if there is no preference.
|
||||||
|
public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape
|
||||||
|
{ get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } }
|
||||||
|
|
||||||
// When the physical properties are updated, an EntityProperty holds the update values.
|
// When the physical properties are updated, an EntityProperty holds the update values.
|
||||||
// Keep the current and last EntityProperties to enable computation of differences
|
// Keep the current and last EntityProperties to enable computation of differences
|
||||||
|
|
|
@ -171,6 +171,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
ForceBodyShapeRebuild(false);
|
ForceBodyShapeRebuild(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Whatever the linkset wants is what I want.
|
||||||
|
public override ShapeData.PhysicsShapeType PreferredPhysicalShape
|
||||||
|
{ get { return Linkset.PreferredPhysicalShape; } }
|
||||||
|
|
||||||
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
||||||
{
|
{
|
||||||
LastAssetBuildFailed = false;
|
LastAssetBuildFailed = false;
|
||||||
|
@ -1310,34 +1314,11 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}// end CalculateMass
|
}// end CalculateMass
|
||||||
#endregion Mass Calculation
|
#endregion Mass Calculation
|
||||||
|
|
||||||
// Copy prim's info into the BulletSim shape description structure
|
|
||||||
public void FillShapeInfo(out ShapeData shape)
|
|
||||||
{
|
|
||||||
shape.ID = LocalID;
|
|
||||||
shape.Type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN;
|
|
||||||
shape.Position = _position;
|
|
||||||
shape.Rotation = _orientation;
|
|
||||||
shape.Velocity = _velocity;
|
|
||||||
shape.Size = _size;
|
|
||||||
shape.Scale = Scale;
|
|
||||||
shape.Mass = _isPhysical ? _mass : 0f;
|
|
||||||
shape.Buoyancy = _buoyancy;
|
|
||||||
shape.HullKey = 0;
|
|
||||||
shape.MeshKey = 0;
|
|
||||||
shape.Friction = _friction;
|
|
||||||
shape.Restitution = _restitution;
|
|
||||||
shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse;
|
|
||||||
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
|
|
||||||
shape.Solid = IsSolid ? ShapeData.numericFalse : ShapeData.numericTrue;
|
|
||||||
}
|
|
||||||
// Rebuild the geometry and object.
|
// Rebuild the geometry and object.
|
||||||
// This is called when the shape changes so we need to recreate the mesh/hull.
|
// This is called when the shape changes so we need to recreate the mesh/hull.
|
||||||
// Called at taint-time!!!
|
// Called at taint-time!!!
|
||||||
private void CreateGeomAndObject(bool forceRebuild)
|
private void CreateGeomAndObject(bool forceRebuild)
|
||||||
{
|
{
|
||||||
ShapeData shapeData;
|
|
||||||
FillShapeInfo(out shapeData);
|
|
||||||
|
|
||||||
// If this prim is part of a linkset, we must remove and restore the physical
|
// If this prim is part of a linkset, we must remove and restore the physical
|
||||||
// links if the body is rebuilt.
|
// links if the body is rebuilt.
|
||||||
bool needToRestoreLinkset = false;
|
bool needToRestoreLinkset = false;
|
||||||
|
@ -1346,8 +1327,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Updates BSBody and BSShape with the new information.
|
// Updates BSBody and BSShape with the new information.
|
||||||
// Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
|
// Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
|
||||||
// Returns 'true' if either the body or the shape was changed.
|
// Returns 'true' if either the body or the shape was changed.
|
||||||
PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, shapeData, BaseShape,
|
PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody)
|
||||||
null, delegate(BulletBody dBody)
|
|
||||||
{
|
{
|
||||||
// Called if the current prim body is about to be destroyed.
|
// Called if the current prim body is about to be destroyed.
|
||||||
// Remove all the physical dependencies on the old body.
|
// Remove all the physical dependencies on the old body.
|
||||||
|
|
|
@ -90,7 +90,6 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// remove the physical constraints before the body is destroyed.
|
// remove the physical constraints before the body is destroyed.
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim,
|
public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim,
|
||||||
ShapeData shapeData, PrimitiveBaseShape pbs,
|
|
||||||
ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
|
ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -101,12 +100,12 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Do we have the correct geometry for this type of object?
|
// Do we have the correct geometry for this type of object?
|
||||||
// Updates prim.BSShape with information/pointers to shape.
|
// Updates prim.BSShape with information/pointers to shape.
|
||||||
// CreateGeom returns 'true' of BSShape as changed to a new shape.
|
// CreateGeom returns 'true' of BSShape as changed to a new shape.
|
||||||
bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback);
|
bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback);
|
||||||
// If we had to select a new shape geometry for the object,
|
// If we had to select a new shape geometry for the object,
|
||||||
// rebuild the body around it.
|
// rebuild the body around it.
|
||||||
// Updates prim.BSBody with information/pointers to requested body
|
// Updates prim.BSBody with information/pointers to requested body
|
||||||
bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World,
|
bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World,
|
||||||
prim.PhysShape, shapeData, bodyCallback);
|
prim.PhysShape, bodyCallback);
|
||||||
ret = newGeom || newBody;
|
ret = newGeom || newBody;
|
||||||
}
|
}
|
||||||
DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}",
|
DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}",
|
||||||
|
@ -261,6 +260,9 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
case ShapeData.PhysicsShapeType.SHAPE_MESH:
|
case ShapeData.PhysicsShapeType.SHAPE_MESH:
|
||||||
DereferenceMesh(shape, shapeCallback);
|
DereferenceMesh(shape, shapeCallback);
|
||||||
break;
|
break;
|
||||||
|
case ShapeData.PhysicsShapeType.SHAPE_COMPOUND:
|
||||||
|
DereferenceCompound(shape, shapeCallback);
|
||||||
|
break;
|
||||||
case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN:
|
case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -317,6 +319,13 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove a reference to a compound shape.
|
||||||
|
// Called at taint-time.
|
||||||
|
private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback)
|
||||||
|
{
|
||||||
|
// Compound shape is made of a bunch of meshes and natives.
|
||||||
|
}
|
||||||
|
|
||||||
// Create the geometry information in Bullet for later use.
|
// Create the geometry information in Bullet for later use.
|
||||||
// The objects needs a hull if it's physical otherwise a mesh is enough.
|
// The objects needs a hull if it's physical otherwise a mesh is enough.
|
||||||
// if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls,
|
// if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls,
|
||||||
|
@ -325,17 +334,17 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Info in prim.BSShape is updated to the new shape.
|
// Info in prim.BSShape is updated to the new shape.
|
||||||
// Returns 'true' if the geometry was rebuilt.
|
// Returns 'true' if the geometry was rebuilt.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeData shapeData,
|
private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
|
||||||
PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback)
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
bool haveShape = false;
|
bool haveShape = false;
|
||||||
bool nativeShapePossible = true;
|
bool nativeShapePossible = true;
|
||||||
|
PrimitiveBaseShape pbs = prim.BaseShape;
|
||||||
|
|
||||||
if (shapeData.Type == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
|
if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
|
||||||
{
|
{
|
||||||
// an avatar capsule is close to a native shape (it is not shared)
|
// an avatar capsule is close to a native shape (it is not shared)
|
||||||
ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
|
ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
|
||||||
ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback);
|
ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
|
DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
@ -359,11 +368,11 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
haveShape = true;
|
haveShape = true;
|
||||||
if (forceRebuild
|
if (forceRebuild
|
||||||
|| prim.Scale != shapeData.Size
|
|| prim.Scale != prim.Size
|
||||||
|| prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
|
|| prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
|
ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
|
||||||
ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback);
|
ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
|
||||||
prim.LocalID, forceRebuild, prim.PhysShape);
|
prim.LocalID, forceRebuild, prim.PhysShape);
|
||||||
|
@ -373,11 +382,11 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
haveShape = true;
|
haveShape = true;
|
||||||
if (forceRebuild
|
if (forceRebuild
|
||||||
|| prim.Scale != shapeData.Size
|
|| prim.Scale != prim.Size
|
||||||
|| prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
|
|| prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX,
|
ret = GetReferenceToNativeShape( prim, ShapeData.PhysicsShapeType.SHAPE_BOX,
|
||||||
ShapeData.FixedShapeKey.KEY_BOX, shapeCallback);
|
ShapeData.FixedShapeKey.KEY_BOX, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
|
||||||
prim.LocalID, forceRebuild, prim.PhysShape);
|
prim.LocalID, forceRebuild, prim.PhysShape);
|
||||||
|
@ -392,15 +401,15 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects)
|
if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects)
|
||||||
{
|
{
|
||||||
// Update prim.BSShape to reference a hull of this shape.
|
// Update prim.BSShape to reference a hull of this shape.
|
||||||
ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback);
|
ret = GetReferenceToHull(prim,shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
|
||||||
shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback);
|
ret = GetReferenceToMesh(prim, shapeCallback);
|
||||||
DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
|
||||||
shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -408,44 +417,45 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// Creates a native shape and assignes it to prim.BSShape.
|
// Creates a native shape and assignes it to prim.BSShape.
|
||||||
// "Native" shapes are never shared. they are created here and destroyed in DereferenceShape().
|
// "Native" shapes are never shared. they are created here and destroyed in DereferenceShape().
|
||||||
private bool GetReferenceToNativeShape(BSPhysObject prim, ShapeData shapeData,
|
private bool GetReferenceToNativeShape(BSPhysObject prim,
|
||||||
ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey,
|
ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey,
|
||||||
ShapeDestructionCallback shapeCallback)
|
ShapeDestructionCallback shapeCallback)
|
||||||
{
|
{
|
||||||
// release any previous shape
|
// release any previous shape
|
||||||
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
||||||
|
|
||||||
shapeData.Type = shapeType;
|
|
||||||
// Bullet native objects are scaled by the Bullet engine so pass the size in
|
// Bullet native objects are scaled by the Bullet engine so pass the size in
|
||||||
prim.Scale = shapeData.Size;
|
prim.Scale = prim.Size;
|
||||||
shapeData.Scale = shapeData.Size;
|
|
||||||
|
|
||||||
BulletShape newShape = BuildPhysicalNativeShape(shapeType, shapeData, shapeKey);
|
BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);
|
||||||
|
|
||||||
// Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
|
// Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
|
||||||
DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
|
DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
|
||||||
shapeData.ID, newShape, shapeData.Scale);
|
prim.LocalID, newShape, prim.Scale);
|
||||||
|
|
||||||
prim.PhysShape = newShape;
|
prim.PhysShape = newShape;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BulletShape BuildPhysicalNativeShape(ShapeData.PhysicsShapeType shapeType,
|
private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, ShapeData.PhysicsShapeType shapeType,
|
||||||
ShapeData shapeData, ShapeData.FixedShapeKey shapeKey)
|
ShapeData.FixedShapeKey shapeKey)
|
||||||
{
|
{
|
||||||
BulletShape newShape;
|
BulletShape newShape;
|
||||||
// Need to make sure the passed shape information is for the native type.
|
// Need to make sure the passed shape information is for the native type.
|
||||||
ShapeData nativeShapeData = shapeData;
|
ShapeData nativeShapeData = new ShapeData();
|
||||||
nativeShapeData.Type = shapeType;
|
nativeShapeData.Type = shapeType;
|
||||||
|
nativeShapeData.ID = prim.LocalID;
|
||||||
|
nativeShapeData.Scale = prim.Scale;
|
||||||
|
nativeShapeData.Size = prim.Scale;
|
||||||
nativeShapeData.MeshKey = (ulong)shapeKey;
|
nativeShapeData.MeshKey = (ulong)shapeKey;
|
||||||
nativeShapeData.HullKey = (ulong)shapeKey;
|
nativeShapeData.HullKey = (ulong)shapeKey;
|
||||||
|
|
||||||
if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
|
if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
|
||||||
{
|
{
|
||||||
newShape = new BulletShape(
|
newShape = new BulletShape(
|
||||||
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, nativeShapeData.Scale)
|
BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale)
|
||||||
, shapeType);
|
, shapeType);
|
||||||
DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", nativeShapeData.ID, nativeShapeData.Scale);
|
DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -454,7 +464,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (newShape.ptr == IntPtr.Zero)
|
if (newShape.ptr == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
|
PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
|
||||||
LogHeader, nativeShapeData.ID, nativeShapeData.Type);
|
LogHeader, prim.LocalID, shapeType);
|
||||||
}
|
}
|
||||||
newShape.shapeKey = (System.UInt64)shapeKey;
|
newShape.shapeKey = (System.UInt64)shapeKey;
|
||||||
newShape.isNativeShape = true;
|
newShape.isNativeShape = true;
|
||||||
|
@ -466,13 +476,12 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Dereferences previous shape in BSShape and adds a reference for this new shape.
|
// Dereferences previous shape in BSShape and adds a reference for this new shape.
|
||||||
// Returns 'true' of a mesh was actually built. Otherwise .
|
// Returns 'true' of a mesh was actually built. Otherwise .
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
private bool GetReferenceToMesh(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs,
|
private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
|
||||||
ShapeDestructionCallback shapeCallback)
|
|
||||||
{
|
{
|
||||||
BulletShape newShape = new BulletShape(IntPtr.Zero);
|
BulletShape newShape = new BulletShape(IntPtr.Zero);
|
||||||
|
|
||||||
float lod;
|
float lod;
|
||||||
System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod);
|
System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||||
|
|
||||||
// if this new shape is the same as last time, don't recreate the mesh
|
// if this new shape is the same as last time, don't recreate the mesh
|
||||||
if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH)
|
if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH)
|
||||||
|
@ -484,9 +493,9 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Since we're recreating new, get rid of the reference to the previous shape
|
// Since we're recreating new, get rid of the reference to the previous shape
|
||||||
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
||||||
|
|
||||||
newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod);
|
newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod);
|
||||||
// Take evasive action if the mesh was not constructed.
|
// Take evasive action if the mesh was not constructed.
|
||||||
newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs);
|
newShape = VerifyMeshCreated(newShape, prim);
|
||||||
|
|
||||||
ReferenceShape(newShape);
|
ReferenceShape(newShape);
|
||||||
|
|
||||||
|
@ -541,13 +550,12 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// See that hull shape exists in the physical world and update prim.BSShape.
|
// See that hull shape exists in the physical world and update prim.BSShape.
|
||||||
// We could be creating the hull because scale changed or whatever.
|
// We could be creating the hull because scale changed or whatever.
|
||||||
private bool GetReferenceToHull(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs,
|
private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
|
||||||
ShapeDestructionCallback shapeCallback)
|
|
||||||
{
|
{
|
||||||
BulletShape newShape;
|
BulletShape newShape;
|
||||||
|
|
||||||
float lod;
|
float lod;
|
||||||
System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod);
|
System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||||
|
|
||||||
// if the hull hasn't changed, don't rebuild it
|
// if the hull hasn't changed, don't rebuild it
|
||||||
if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL)
|
if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL)
|
||||||
|
@ -559,8 +567,8 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Remove usage of the previous shape.
|
// Remove usage of the previous shape.
|
||||||
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
DereferenceShape(prim.PhysShape, true, shapeCallback);
|
||||||
|
|
||||||
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod);
|
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||||
newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs);
|
newShape = VerifyMeshCreated(newShape, prim);
|
||||||
|
|
||||||
ReferenceShape(newShape);
|
ReferenceShape(newShape);
|
||||||
|
|
||||||
|
@ -687,7 +695,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
|
|
||||||
// Create a hash of all the shape parameters to be used as a key
|
// Create a hash of all the shape parameters to be used as a key
|
||||||
// for this particular shape.
|
// for this particular shape.
|
||||||
private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod)
|
private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod)
|
||||||
{
|
{
|
||||||
// level of detail based on size and type of the object
|
// level of detail based on size and type of the object
|
||||||
float lod = PhysicsScene.MeshLOD;
|
float lod = PhysicsScene.MeshLOD;
|
||||||
|
@ -695,40 +703,40 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
lod = PhysicsScene.SculptLOD;
|
lod = PhysicsScene.SculptLOD;
|
||||||
|
|
||||||
// Mega prims usually get more detail because one can interact with shape approximations at this size.
|
// Mega prims usually get more detail because one can interact with shape approximations at this size.
|
||||||
float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z));
|
float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z));
|
||||||
if (maxAxis > PhysicsScene.MeshMegaPrimThreshold)
|
if (maxAxis > PhysicsScene.MeshMegaPrimThreshold)
|
||||||
lod = PhysicsScene.MeshMegaPrimLOD;
|
lod = PhysicsScene.MeshMegaPrimLOD;
|
||||||
|
|
||||||
retLod = lod;
|
retLod = lod;
|
||||||
return pbs.GetMeshKey(shapeData.Size, lod);
|
return pbs.GetMeshKey(size, lod);
|
||||||
}
|
}
|
||||||
// For those who don't want the LOD
|
// For those who don't want the LOD
|
||||||
private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs)
|
private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs)
|
||||||
{
|
{
|
||||||
float lod;
|
float lod;
|
||||||
return ComputeShapeKey(shapeData, pbs, out lod);
|
return ComputeShapeKey(size, pbs, out lod);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The creation of a mesh or hull can fail if an underlying asset is not available.
|
// The creation of a mesh or hull can fail if an underlying asset is not available.
|
||||||
// There are two cases: 1) the asset is not in the cache and it needs to be fetched;
|
// There are two cases: 1) the asset is not in the cache and it needs to be fetched;
|
||||||
// and 2) the asset cannot be converted (like decompressing JPEG2000s).
|
// and 2) the asset cannot be converted (like failed decompression of JPEG2000s).
|
||||||
// The first case causes the asset to be fetched. The second case just requires
|
// The first case causes the asset to be fetched. The second case requires
|
||||||
// us to not loop forever.
|
// us to not loop forever.
|
||||||
// Called after creating a physical mesh or hull. If the physical shape was created,
|
// Called after creating a physical mesh or hull. If the physical shape was created,
|
||||||
// just return.
|
// just return.
|
||||||
private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs)
|
private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim)
|
||||||
{
|
{
|
||||||
// If the shape was successfully created, nothing more to do
|
// If the shape was successfully created, nothing more to do
|
||||||
if (newShape.ptr != IntPtr.Zero)
|
if (newShape.ptr != IntPtr.Zero)
|
||||||
return newShape;
|
return newShape;
|
||||||
|
|
||||||
// If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
|
// If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
|
||||||
if (pbs.SculptEntry && !prim.LastAssetBuildFailed && pbs.SculptTexture != OMV.UUID.Zero)
|
if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero)
|
||||||
{
|
{
|
||||||
prim.LastAssetBuildFailed = true;
|
prim.LastAssetBuildFailed = true;
|
||||||
BSPhysObject xprim = prim;
|
BSPhysObject xprim = prim;
|
||||||
DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}",
|
DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}",
|
||||||
LogHeader, shapeData.ID.ToString("X"), prim.LastAssetBuildFailed);
|
LogHeader, prim.LocalID, prim.LastAssetBuildFailed);
|
||||||
Util.FireAndForget(delegate
|
Util.FireAndForget(delegate
|
||||||
{
|
{
|
||||||
RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod;
|
RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod;
|
||||||
|
@ -745,7 +753,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
yprim.BaseShape.SculptData = asset.Data;
|
yprim.BaseShape.SculptData = asset.Data;
|
||||||
// This will cause the prim to see that the filler shape is not the right
|
// This will cause the prim to see that the filler shape is not the right
|
||||||
// one and try again to build the object.
|
// one and try again to build the object.
|
||||||
// No race condition with the native sphere setting since the rebuild is at taint time.
|
// No race condition with the normal shape setting since the rebuild is at taint time.
|
||||||
yprim.ForceBodyShapeRebuild(false);
|
yprim.ForceBodyShapeRebuild(false);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -757,13 +765,13 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (prim.LastAssetBuildFailed)
|
if (prim.LastAssetBuildFailed)
|
||||||
{
|
{
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
|
PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
|
||||||
LogHeader, shapeData.ID, pbs.SculptTexture);
|
LogHeader, prim.LocalID, prim.BaseShape.SculptTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// While we figure out the real problem, stick a simple native shape on the object.
|
// While we figure out the real problem, stick a simple native shape on the object.
|
||||||
BulletShape fillinShape =
|
BulletShape fillinShape =
|
||||||
BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_BOX, shapeData, ShapeData.FixedShapeKey.KEY_BOX);
|
BuildPhysicalNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX);
|
||||||
|
|
||||||
return fillinShape;
|
return fillinShape;
|
||||||
}
|
}
|
||||||
|
@ -773,7 +781,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Returns 'true' if an object was actually created.
|
// Returns 'true' if an object was actually created.
|
||||||
// Called at taint-time.
|
// Called at taint-time.
|
||||||
private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape,
|
private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape,
|
||||||
ShapeData shapeData, BodyDestructionCallback bodyCallback)
|
BodyDestructionCallback bodyCallback)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
@ -803,16 +811,16 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
if (prim.IsSolid)
|
if (prim.IsSolid)
|
||||||
{
|
{
|
||||||
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
|
bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr,
|
||||||
shapeData.ID, shapeData.Position, shapeData.Rotation);
|
prim.LocalID, prim.ForcePosition, prim.ForceOrientation);
|
||||||
DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
|
bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr,
|
||||||
shapeData.ID, shapeData.Position, shapeData.Rotation);
|
prim.LocalID, prim.ForcePosition, prim.ForceOrientation);
|
||||||
DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X"));
|
||||||
}
|
}
|
||||||
aBody = new BulletBody(shapeData.ID, bodyPtr);
|
aBody = new BulletBody(prim.LocalID, bodyPtr);
|
||||||
|
|
||||||
ReferenceBody(aBody, true);
|
ReferenceBody(aBody, true);
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,7 @@ public struct ShapeData
|
||||||
// following defined by BulletSim
|
// following defined by BulletSim
|
||||||
SHAPE_GROUNDPLANE = 20,
|
SHAPE_GROUNDPLANE = 20,
|
||||||
SHAPE_TERRAIN = 21,
|
SHAPE_TERRAIN = 21,
|
||||||
|
SHAPE_COMPOUND = 22,
|
||||||
};
|
};
|
||||||
public uint ID;
|
public uint ID;
|
||||||
public PhysicsShapeType Type;
|
public PhysicsShapeType Type;
|
||||||
|
|
Loading…
Reference in New Issue