void PrimPosAndRot(SceneObject obj, out Vector3 pos, out Quaternion rot)
{
// Sanity check
if (obj == null)
{
pos = RHelp.InvalidPosition;
rot = Quaternion.Identity;
return;
}
if (obj.BasePrim.ParentID == 0)
{
// We are the root prim, return our interpolated position
pos = obj.InterpolatedPosition;
rot = obj.InterpolatedRotation;
return;
}
else
{
pos = RHelp.InvalidPosition;
rot = Quaternion.Identity;
// Not root, find our parent
SceneObject p = GetSceneObject(obj.BasePrim.ParentID);
if (p == null) return;
// If we don't know parent position, recursively find out
if (!p.PositionCalculated)
{
PrimPosAndRot(p, out p.RenderPosition, out p.RenderRotation);
p.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, p.RenderPosition);
p.PositionCalculated = true;
}
Vector3 parentPos = p.RenderPosition;
Quaternion parentRot = p.RenderRotation;
if (p is RenderPrimitive)
{
// Child prim (our parent is another prim here)
pos = parentPos + obj.InterpolatedPosition * parentRot;
rot = parentRot * obj.InterpolatedRotation;
}
else if (p is RenderAvatar)
{
// Calculating position and rotation of the root prim of an attachment here
// (our parent is an avatar here)
RenderAvatar parentav = (RenderAvatar)p;
// Check for invalid attachment point
int attachment_index = (int)obj.BasePrim.PrimData.AttachmentPoint;
if (attachment_index >= GLAvatar.attachment_points.Count()) return;
attachment_point apoint = GLAvatar.attachment_points[attachment_index];
skeleton skel = parentav.glavatar.skel;
if (!skel.mBones.ContainsKey(apoint.joint)) return;
// Bone position and rotation
Bone bone = skel.mBones[apoint.joint];
Vector3 bpos = bone.getTotalOffset();
Quaternion brot = bone.getTotalRotation();
// Start with avatar positon
pos = parentPos;
rot = parentRot;
// Move by pelvis offset
// FIXME 2 dictionay lookups via string key in render loop!
// pos -= (parentav.glavatar.skel.mBones["mPelvis"].animation_offset * parentav.RenderRotation) + parentav.glavatar.skel.getOffset("mPelvis") * rot;
//pos -= parentav.glavatar.skel.getOffset("mPelvis") * rot;
//rot = parentav.glavatar.skel.getRotation("mPelvis") * rot;
pos = parentav.AdjustedPosition(pos);
// Translate and rotate to the joint calculated position
pos += bpos * rot;
rot *= brot;
// Translate and rotate built in joint offset
pos += apoint.position * rot;
rot *= apoint.rotation;
// Translate and rotate from the offset from the attachment point
// set in teh appearance editor
pos += obj.BasePrim.Position * rot;
rot *= obj.BasePrim.Rotation;
}
return;
}
}