Matrix3 plMaxNodeBase::GetVertToLocal(TimeValue t) { Matrix3 objectTM; // // If animated or we want forced into local space // still return OTM to fold into vertices // if( GetForceLocal() ) { return GetOTM(t); } // otherwise flatten our local to parent into the verts // note that our parent may have flattened their l2p into // their v2l as well. // so // objectTM = v2l * l2p * parentL2W // objectTM * Inverse(parentL2W) = v2l * l2p // objectTM * parentW2L = v2l (w/ l2p folded in) // // Objects transformation ObjectTM = OTM * nodeTM objectTM = GetObjectTM(t); Matrix3 w2p(true); if( !GetParentNode()->IsRootNode() ) w2p = GetWorldToParent(t); Matrix3 v2l = objectTM * w2p; return v2l; }
// TransformedPrimitive Method Definitions bool TransformedPrimitive::Intersect(const Ray &r, Intersection *isect) const { Transform w2p; WorldToPrimitive.Interpolate(r.time, &w2p); Ray ray = w2p(r); if (!primitive->Intersect(ray, isect)) return false; r.maxt = ray.maxt; isect->primitiveId = primitiveId; if (!w2p.IsIdentity()) { // Compute world-to-object transformation for instance isect->WorldToObject = isect->WorldToObject * w2p; isect->ObjectToWorld = Inverse(isect->WorldToObject); // Transform instance's differential geometry to world space Transform PrimitiveToWorld = Inverse(w2p); isect->dg.p = PrimitiveToWorld(isect->dg.p); isect->dg.nn = Normalize(PrimitiveToWorld(isect->dg.nn)); isect->dg.dpdu = PrimitiveToWorld(isect->dg.dpdu); isect->dg.dpdv = PrimitiveToWorld(isect->dg.dpdv); isect->dg.dndu = PrimitiveToWorld(isect->dg.dndu); isect->dg.dndv = PrimitiveToWorld(isect->dg.dndv); } return true; }
Matrix3 plMaxNodeBase::GetLocalToParent(TimeValue t) { // l2w = l2p * parentL2W // l2w * Inverse(parentL2W) = l2p // l2w * parentW2L = l2p Matrix3 l2w = GetLocalToWorld(t); Matrix3 w2p(true); if( !GetParentNode()->IsRootNode() ) w2p = GetWorldToParent(t); Matrix3 l2p = l2w * w2p; return l2p; }