//---------------------------------------------------------------- /// Get World Transform /// /// @return The tranform in relation to its parent transform //---------------------------------------------------------------- const Matrix4& Transform::GetWorldTransform() const { //If we have a parent transform we must apply it to //our local transform to get the relative transformation if(mpParentTransform) { //Our parent has changed so we must re-calculate our transform if(!mbIsParentTransformCacheValid) { mbIsParentTransformCacheValid = true; //Calculate the relative transform with our new parent transform mmatWorldTransform = GetLocalTransform() * mpParentTransform->GetWorldTransform(); } //Our local transform has changed therefore we must update else if(!mbIsTransformCacheValid) { //Calculate the relative transformation from our cached parent mmatWorldTransform = GetLocalTransform() * mpParentTransform->GetWorldTransform(); } } //We do not have a parent so our relative transform is actually just our local one else if(!mbIsTransformCacheValid) { mmatWorldTransform = GetLocalTransform(); } return mmatWorldTransform; }
const Matrix4x4 CStructure::GetPhysicsTransform() const { CPlanet* pPlanet = GameData().GetPlanet(); if (!pPlanet) return GetLocalTransform(); if (!pPlanet->GetChunkManager()->HasGroupCenter()) return GetLocalTransform(); return GameData().GetGroupTransform(); }
void ImageLayer::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) { gfx::Matrix4x4 local = GetLocalTransform(); // Snap image edges to pixel boundaries gfxRect sourceRect(0, 0, 0, 0); if (mContainer) { sourceRect.SizeTo(gfx::ThebesIntSize(mContainer->GetCurrentSize())); if (mScaleMode != ScaleMode::SCALE_NONE && sourceRect.width != 0.0 && sourceRect.height != 0.0) { NS_ASSERTION(mScaleMode == ScaleMode::STRETCH, "No other scalemodes than stretch and none supported yet."); local.PreScale(mScaleToSize.width / sourceRect.width, mScaleToSize.height / sourceRect.height, 1.0); } } // Snap our local transform first, and snap the inherited transform as well. // This makes our snapping equivalent to what would happen if our content // was drawn into a PaintedLayer (gfxContext would snap using the local // transform, then we'd snap again when compositing the PaintedLayer). mEffectiveTransform = SnapTransform(local, sourceRect, nullptr) * SnapTransformTranslation(aTransformToSurface, nullptr); ComputeEffectiveTransformForMaskLayer(aTransformToSurface); }
bool CStructure::CanAutoCloseMenu() const { CPlayerCharacter* pOwner = GetOwner()->GetPlayerCharacter(); if (!pOwner) return false; if (GetOwner()->IsInBlockPlaceMode()) return true; if (GetOwner()->IsInBlockDesignateMode()) return true; if (GetOwner()->IsInConstructionMode()) return true; TVector vecPlayerEyes = pOwner->GetLocalOrigin() + pOwner->EyeHeight() * DoubleVector(pOwner->GetLocalUpVector()); TVector vecOwnerProjectionPoint = GetLocalOrigin() + GetLocalTransform().TransformVector(GameData().GetCommandMenuRenderOffset()); Vector vecToPlayerEyes = (vecPlayerEyes - vecOwnerProjectionPoint).GetMeters(); float flDistanceToPlayerEyes = vecToPlayerEyes.Length(); Vector vecProjectionDirection = vecToPlayerEyes/flDistanceToPlayerEyes; float flViewAngleDot = AngleVector(pOwner->GetViewAngles()).Dot(vecProjectionDirection); if (GameData().GetCommandMenu() && (GameData().GetCommandMenu()->WantsToClose() || flDistanceToPlayerEyes > 5 || flViewAngleDot > -0.7)) return true; return false; }
void BMaxObject::UpdateGeometry() { SetGeometryDirty(false); if (m_pAnimatedMesh && m_pAnimatedMesh->IsLoaded()) { Vector3 vMin, vMax; if (m_pAnimatedMesh->GetBoundingBox(&vMin, &vMax)) { Matrix4 mat; GetLocalTransform(&mat); CShapeOBB obb(CShapeBox(vMin, vMax), mat); CShapeBox minmaxBox; minmaxBox.Extend(obb); if (GetScaling()!= 1.0){ minmaxBox.SetMinMax(minmaxBox.GetMin() * GetScaling(), minmaxBox.GetMax() * GetScaling()); } SetAABB(&minmaxBox.GetMin(), &minmaxBox.GetMax()); } UnloadPhysics(); if (m_dwPhysicsMethod == 0) m_dwPhysicsMethod = PHYSICS_LAZY_LOAD; else if (IsPhysicsEnabled() && ((m_dwPhysicsMethod&PHYSICS_ALWAYS_LOAD)>0)) { LoadPhysics(); } } }
void ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) { gfx3DMatrix local = GetLocalTransform(); // Snap image edges to pixel boundaries gfxRect sourceRect(0, 0, 0, 0); if (mImageHost && mImageHost->IsAttached() && (mImageHost->GetDeprecatedTextureHost() || mImageHost->GetTextureHost())) { IntSize size = mImageHost->GetTextureHost() ? mImageHost->GetTextureHost()->GetSize() : mImageHost->GetDeprecatedTextureHost()->GetSize(); sourceRect.SizeTo(size.width, size.height); if (mScaleMode != SCALE_NONE && sourceRect.width != 0.0 && sourceRect.height != 0.0) { NS_ASSERTION(mScaleMode == SCALE_STRETCH, "No other scalemodes than stretch and none supported yet."); local.Scale(mScaleToSize.width / sourceRect.width, mScaleToSize.height / sourceRect.height, 1.0); } } // Snap our local transform first, and snap the inherited transform as well. // This makes our snapping equivalent to what would happen if our content // was drawn into a ThebesLayer (gfxContext would snap using the local // transform, then we'd snap again when compositing the ThebesLayer). mEffectiveTransform = SnapTransform(local, sourceRect, nullptr) * SnapTransformTranslation(aTransformToSurface, nullptr); ComputeEffectiveTransformForMaskLayer(aTransformToSurface); }
void ImageLayerMLGPU::ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) { Matrix4x4 local = GetLocalTransform(); // Snap image edges to pixel boundaries. gfxRect sourceRect(0, 0, 0, 0); if (mHost && mHost->IsAttached()) { IntSize size = mHost->GetImageSize(); sourceRect.SizeTo(size.width, size.height); } // Snap our local transform first, and snap the inherited transform as well. // This makes our snapping equivalent to what would happen if our content // was drawn into a PaintedLayer (gfxContext would snap using the local // transform, then we'd snap again when compositing the PaintedLayer). mEffectiveTransform = SnapTransform(local, sourceRect, nullptr) * SnapTransformTranslation(aTransformToSurface, nullptr); mEffectiveTransformForBuffer = mEffectiveTransform; if (mScaleMode == ScaleMode::STRETCH && mScaleToSize.width != 0.0 && mScaleToSize.height != 0.0) { Size scale(sourceRect.Width() / mScaleToSize.width, sourceRect.Height() / mScaleToSize.height); mScale = Some(scale); } ComputeEffectiveTransformForMaskLayers(aTransformToSurface); }
void ContainerLayer::DefaultComputeEffectiveTransforms(const Matrix4x4& aTransformToSurface) { Matrix residual; Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; idealTransform.ProjectTo2D(); mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual); bool useIntermediateSurface; if (GetMaskLayer() || GetForceIsolatedGroup()) { useIntermediateSurface = true; #ifdef MOZ_DUMP_PAINTING } else if (gfxUtils::sDumpPainting) { useIntermediateSurface = true; #endif } else { float opacity = GetEffectiveOpacity(); CompositionOp blendMode = GetEffectiveMixBlendMode(); if ((opacity != 1.0f || blendMode != CompositionOp::OP_OVER) && HasMultipleChildren()) { useIntermediateSurface = true; } else { useIntermediateSurface = false; gfx::Matrix contTransform; if (!mEffectiveTransform.Is2D(&contTransform) || #ifdef MOZ_GFX_OPTIMIZE_MOBILE !contTransform.PreservesAxisAlignedRectangles()) { #else gfx::ThebesMatrix(contTransform).HasNonIntegerTranslation()) { #endif for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) { const nsIntRect *clipRect = child->GetEffectiveClipRect(); /* We can't (easily) forward our transform to children with a non-empty clip * rect since it would need to be adjusted for the transform. See * the calculations performed by CalculateScissorRect above. * Nor for a child with a mask layer. */ if ((clipRect && !clipRect->IsEmpty() && !child->GetVisibleRegion().IsEmpty()) || child->GetMaskLayer()) { useIntermediateSurface = true; break; } } } } } mUseIntermediateSurface = useIntermediateSurface; if (useIntermediateSurface) { ComputeEffectiveTransformsForChildren(Matrix4x4::From2D(residual)); } else { ComputeEffectiveTransformsForChildren(idealTransform); } if (idealTransform.CanDraw2D()) { ComputeEffectiveTransformForMaskLayer(aTransformToSurface); } else { ComputeEffectiveTransformForMaskLayer(Matrix4x4()); } }
bool CStructure::CanAutoOpenMenu() const { CPlayerCharacter* pOwner = GetOwner()->GetPlayerCharacter(); if (!pOwner) return false; if (GetOwner()->IsInBlockPlaceMode()) return false; if (GetOwner()->IsInBlockDesignateMode()) return false; if (GetOwner()->IsInConstructionMode()) return false; TVector vecPlayerEyes = pOwner->GetLocalOrigin() + pOwner->EyeHeight() * DoubleVector(pOwner->GetLocalUpVector()); TVector vecOwnerProjectionPoint = GetLocalOrigin() + GetLocalTransform().TransformVector(GameData().GetCommandMenuRenderOffset()); Vector vecToPlayerEyes = (vecPlayerEyes - vecOwnerProjectionPoint).GetMeters(); float flDistanceToPlayerEyes = vecToPlayerEyes.Length(); Vector vecProjectionDirection = vecToPlayerEyes/flDistanceToPlayerEyes; float flViewAngleDot = AngleVector(pOwner->GetViewAngles()).Dot(vecProjectionDirection); CSPPlayer* pPlayerOwner = static_cast<CSPPlayer*>(pOwner->GetControllingPlayer()); if (!GameData().GetCommandMenu() && flDistanceToPlayerEyes < 4 && flViewAngleDot < -0.8 && !pPlayerOwner->GetActiveCommandMenu()) return true; return false; }
void CylinderCollider::Awake() { auto go = GetGameObject(); auto& trans = go->GetLocalTransform(); auto& btTrans = trans.GetBtTransform(); float halfX = m_halfExtents.x; float halfY = m_halfExtents.y; float halfZ = m_halfExtents.z; halfX *= trans.Scale.x; halfY *= trans.Scale.y; halfZ *= trans.Scale.z; m_collisionShape = new btCylinderShape(btVector3(halfX, halfY, halfZ)); btVector3 inertia; m_collisionShape->calculateLocalInertia(Mass, inertia); m_defaultMotionState = new btDefaultMotionState(btTrans); btRigidBody::btRigidBodyConstructionInfo rbci(Mass, m_defaultMotionState, m_collisionShape, inertia); m_rigidBody = new btRigidBody(rbci); m_world->AddCollider(this); }
void BasicContainerLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) { // We push groups for container layers if we need to, which always // are aligned in device space, so it doesn't really matter how we snap // containers. gfxMatrix residual; gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface; idealTransform.ProjectTo2D(); if (!idealTransform.CanDraw2D()) { mEffectiveTransform = idealTransform; ComputeEffectiveTransformsForChildren(gfx3DMatrix()); ComputeEffectiveTransformForMaskLayer(gfx3DMatrix()); mUseIntermediateSurface = true; return; } mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual); // We always pass the ideal matrix down to our children, so there is no // need to apply any compensation using the residual from SnapTransformTranslation. ComputeEffectiveTransformsForChildren(idealTransform); ComputeEffectiveTransformForMaskLayer(aTransformToSurface); /* If we have a single child, it can just inherit our opacity, * otherwise we need a PushGroup and we need to mark ourselves as using * an intermediate surface so our children don't inherit our opacity * via GetEffectiveOpacity. * Having a mask layer always forces our own push group */ mUseIntermediateSurface = GetMaskLayer() || (GetEffectiveOpacity() != 1.0 && HasMultipleChildren()); }
float3x4 SceneNode::GetWorldTransform()const { float3x4 mat = GetLocalTransform().transform_; if (father_&&(transform_code_&EffectByFather)) { float3x4 fmat = FatherSceneNode()->GetWorldTransform(); mat = fmat*mat; } return mat; }
Transform TransformComponent::GetWorldTransform() { if (worlddirty) { // the inverse is out of date // so it needs to be updated // the worldToLocalMatrix is the inverse of // the localToWorldMatrix world = GetLocalTransform().Get().Inverse(); // clear the dirty flag since the // matrix is now up to date worlddirty = false; } return world; }
void BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSurface) { // We push groups for container layers if we need to, which always // are aligned in device space, so it doesn't really matter how we snap // containers. Matrix residual; Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; idealTransform.ProjectTo2D(); if (!idealTransform.CanDraw2D()) { mEffectiveTransform = idealTransform; ComputeEffectiveTransformsForChildren(Matrix4x4()); ComputeEffectiveTransformForMaskLayer(Matrix4x4()); mUseIntermediateSurface = true; return; } mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual); // We always pass the ideal matrix down to our children, so there is no // need to apply any compensation using the residual from SnapTransformTranslation. ComputeEffectiveTransformsForChildren(idealTransform); ComputeEffectiveTransformForMaskLayer(aTransformToSurface); Layer* child = GetFirstChild(); bool hasSingleBlendingChild = false; if (!HasMultipleChildren() && child) { hasSingleBlendingChild = child->GetMixBlendMode() != CompositionOp::OP_OVER; } /* If we have a single childand it is not blending,, it can just inherit our opacity, * otherwise we need a PushGroup and we need to mark ourselves as using * an intermediate surface so our children don't inherit our opacity * via GetEffectiveOpacity. * Having a mask layer always forces our own push group * Having a blend mode also always forces our own push group */ mUseIntermediateSurface = GetMaskLayer() || GetForceIsolatedGroup() || (GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) || (GetEffectiveOpacity() != 1.0 && (HasMultipleChildren() || hasSingleBlendingChild)); }
//---------------------------------------------------------------------------- PX2::Node *SceneBuilder::BuildNode(INode *maxNode, PX2::Node *relatParent) { PX2::Node *child = new0 PX2::Node; child->SetName(maxNode->GetName()); child->LocalTransform = GetLocalTransform(maxNode, mTimeStart); relatParent->AttachChild(child); TSTR strUserData; maxNode->GetUserPropBuffer(strUserData); if (strstr(strUserData, "a")) { int anchorID = 0; maxNode->GetUserPropInt("a", anchorID); child->SetAnchorID(anchorID); } return child; }
void ContainerLayer::DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) { gfxMatrix residual; gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface; mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), &residual); PRBool useIntermediateSurface; float opacity = GetEffectiveOpacity(); if (opacity != 1.0f && HasMultipleChildren()) { useIntermediateSurface = PR_TRUE; } else { useIntermediateSurface = PR_FALSE; gfxMatrix contTransform; if (!mEffectiveTransform.Is2D(&contTransform) || !contTransform.PreservesAxisAlignedRectangles()) { for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) { const nsIntRect *clipRect = child->GetEffectiveClipRect(); /* We can't (easily) forward our transform to children with a non-empty clip * rect since it would need to be adjusted for the transform. * TODO: This is easily solvable for translation/scaling transforms. */ if (clipRect && !clipRect->IsEmpty() && !child->GetVisibleRegion().IsEmpty()) { useIntermediateSurface = PR_TRUE; break; } } } } mUseIntermediateSurface = useIntermediateSurface; if (useIntermediateSurface) { ComputeEffectiveTransformsForChildren(gfx3DMatrix::From2D(residual)); } else { ComputeEffectiveTransformsForChildren(idealTransform); } }
void CCharacter::MoveThink() { if (!GetGroundEntity()) return; if (m_vecGoalVelocity.LengthSqr()) m_vecGoalVelocity.Normalize(); m_vecMoveVelocity.x = Approach(m_vecGoalVelocity.x, m_vecMoveVelocity.x, GameServer()->GetFrameTime()*4); m_vecMoveVelocity.y = 0; m_vecMoveVelocity.z = Approach(m_vecGoalVelocity.z, m_vecMoveVelocity.z, GameServer()->GetFrameTime()*4); if (m_vecMoveVelocity.LengthSqr() > 0) { TMatrix m = GetLocalTransform(); Vector vecUp = GetUpVector(); if (HasMoveParent()) { TMatrix mGlobalToLocal = GetMoveParent()->GetGlobalToLocalTransform(); vecUp = mGlobalToLocal.TransformNoTranslate(vecUp); } Vector vecRight = m.GetForwardVector().Cross(vecUp).Normalized(); Vector vecForward = vecUp.Cross(vecRight).Normalized(); m.SetColumn(0, vecForward); m.SetColumn(1, vecUp); m.SetColumn(2, vecRight); TVector vecMove = m_vecMoveVelocity * CharacterSpeed(); TVector vecLocalVelocity = m.TransformNoTranslate(vecMove); SetLocalVelocity(vecLocalVelocity); } else SetLocalVelocity(TVector()); eastl::vector<CEntityHandle<CBaseEntity> > apCollisionList; size_t iMaxEntities = GameServer()->GetMaxEntities(); for (size_t j = 0; j < iMaxEntities; j++) { CBaseEntity* pEntity2 = CBaseEntity::GetEntity(j); if (!pEntity2) continue; if (pEntity2->IsDeleted()) continue; if (pEntity2 == this) continue; if (!pEntity2->ShouldCollide()) continue; apCollisionList.push_back(pEntity2); } TMatrix mGlobalToLocalRotation; if (HasMoveParent()) { mGlobalToLocalRotation = GetMoveParent()->GetGlobalToLocalTransform(); mGlobalToLocalRotation.SetTranslation(TVector()); } float flSimulationFrameTime = 0.01f; // Break simulations up into consistent small steps to preserve accuracy. for (; m_flMoveSimulationTime < GameServer()->GetGameTime(); m_flMoveSimulationTime += flSimulationFrameTime) { TVector vecVelocity = GetLocalVelocity(); TVector vecLocalOrigin = GetLocalOrigin(); TVector vecGlobalOrigin = GetGlobalOrigin(); vecVelocity = vecVelocity * flSimulationFrameTime; TVector vecLocalDestination = vecLocalOrigin + vecVelocity; TVector vecGlobalDestination = vecLocalDestination; if (GetMoveParent()) vecGlobalDestination = GetMoveParent()->GetGlobalTransform() * vecLocalDestination; TVector vecNewLocalOrigin = vecLocalDestination; size_t iTries = 0; while (true) { iTries++; TVector vecPoint, vecNormal; TVector vecLocalCollisionPoint, vecGlobalCollisionPoint; bool bContact = false; for (size_t i = 0; i < apCollisionList.size(); i++) { CBaseEntity* pEntity2 = apCollisionList[i]; if (GetMoveParent() == pEntity2) { if (pEntity2->CollideLocal(vecLocalOrigin, vecLocalDestination, vecPoint, vecNormal)) { bContact = true; Touching(pEntity2); vecLocalCollisionPoint = vecPoint; vecGlobalCollisionPoint = GetMoveParent()->GetGlobalTransform() * vecPoint; } } else { if (pEntity2->Collide(vecGlobalOrigin, vecGlobalDestination, vecPoint, vecNormal)) { bContact = true; Touching(pEntity2); vecGlobalCollisionPoint = vecPoint; if (GetMoveParent()) { vecLocalCollisionPoint = GetMoveParent()->GetGlobalToLocalTransform() * vecPoint; vecNormal = GetMoveParent()->GetGlobalToLocalTransform().TransformNoTranslate(vecNormal); } else vecLocalCollisionPoint = vecGlobalCollisionPoint; } } } if (bContact) { vecNewLocalOrigin = vecLocalCollisionPoint; vecVelocity -= vecLocalCollisionPoint - vecLocalOrigin; } if (!bContact) break; if (iTries > 4) break; vecLocalOrigin = vecLocalCollisionPoint; vecGlobalOrigin = vecGlobalCollisionPoint; // Clip the velocity to the surface normal of whatever we hit. TFloat flDistance = vecVelocity.Dot(vecNormal); vecVelocity = vecVelocity - vecNormal * flDistance; // Do it one more time just to make sure we're not headed towards the plane. TFloat flAdjust = vecVelocity.Dot(vecNormal); if (flAdjust < 0.0f) vecVelocity -= (vecNormal * flAdjust); vecLocalDestination = vecLocalOrigin + vecVelocity; if (GetMoveParent()) vecGlobalDestination = GetMoveParent()->GetGlobalTransform() * vecLocalDestination; else vecGlobalDestination = vecLocalDestination; SetLocalVelocity(vecVelocity.Normalized() * GetLocalVelocity().Length()); } SetLocalOrigin(vecNewLocalOrigin); // Try to keep the player on the ground. // Untested. /*TVector vecStart = GetGlobalOrigin() + GetGlobalTransform().GetUpVector()*m_flMaxStepSize; TVector vecEnd = GetGlobalOrigin() - GetGlobalTransform().GetUpVector()*m_flMaxStepSize; // First go up a bit TVector vecHit, vecNormal; Game()->TraceLine(GetGlobalOrigin(), vecStart, vecHit, vecNormal, NULL); vecStart = vecHit; // Now see if there's ground underneath us. bool bHit = Game()->TraceLine(vecStart, vecEnd, vecHit, vecNormal, NULL); if (bHit && vecNormal.y >= TFloat(0.7f)) SetGlobalOrigin(vecHit);*/ m_flMoveSimulationTime += flSimulationFrameTime; } }
//---------------------------------------------------------------------------- PX2::Movable *SceneBuilder::BuildMesh(INode *maxNode, PX2::Node *relatParentOrEqualNode) { // 将Max的三角形网格数据转换到一个或者更多的等价的Phoenix2三角形网格。 // // maxNode: // Max场景图中的Mesh节点。 // relatParentOrEqualNode: // 在Phoenix2场景图系统中最新创建的父亲节点。 // 返回在Phoenix2场景中指向新的孩子节点的指针,这个指针直接指向TriMesh物体; // 或者是一个“link”节点,“link”的多个孩子TriMesh代表Max中的多个孩子mesh。 bool needDel = false; TriObject *triObject = GetTriObject(maxNode, &needDel); if (!triObject) { return 0; } Mesh *maxMesh = &triObject->GetMesh(); Mtl *mtl = maxNode->GetMtl(); int mtlIndex = mMtls.GetIndex(mtl); // 判断这个Max的几何图形节点是否有“子几何图形节点”,如果有子几何图形节点 // isEqualNode为真,反之为假。 // 如果名称相等,就不是relatParentOrEqualNode了,而是equalNode PX2::Movable *link = 0; bool isEqualNode = (relatParentOrEqualNode->GetName().length()>0 && strcmp(maxNode->GetName(), relatParentOrEqualNode->GetName().c_str()) == 0); // maxName char *maxName = maxNode->GetName(); // 如果只需要一个Phoenix的Mesh表示Max的Mesh,直接将Phoenix的Mesh链接到 // Phoenix的场景图中;否则,创建一个"link"节点,将按照材质分割的子Mesh // 放在"link"下。 int i; std::vector<UniMaterialMesh*> uMeshs; SplitGeometry(maxMesh, mtlIndex, uMeshs); if ((int)uMeshs.size() > 1) { if (!isEqualNode) { link = BuildNode(maxNode, relatParentOrEqualNode); } else { link = relatParentOrEqualNode; } assertion(link->IsDerived(PX2::Node::TYPE), "link must be a Node."); for (i=0; i<(int)uMeshs.size(); i++) { PX2::TriMesh *triMesh = uMeshs[i]->ToTriMesh(); if (triMesh) { char meshNumber[6]; sprintf_s(meshNumber, 6, "_%d", i+1); size_t size = strlen(maxName) + strlen(meshNumber) + 1; char *tdName = new1<char>((int)size); strcpy_s(tdName, size, maxName); strcat_s(tdName, size, meshNumber); triMesh->SetName(tdName); delete1(tdName); ((PX2::Node*)link)->AttachChild(triMesh); } } } else if ((int)uMeshs.size() == 1) { PX2::TriMesh *triMesh = uMeshs[0]->ToTriMesh(); if (triMesh) { if (!isEqualNode) { triMesh->SetName(maxName); triMesh->LocalTransform = GetLocalTransform(maxNode, mTimeStart); } else { size_t size = strlen(maxName) + 3; char *tdName = new1<char>((int)size); strcpy_s(tdName, size, maxName); strcat_s(tdName, size, "_1"); triMesh->SetName(tdName); delete1(tdName); } assertion(relatParentOrEqualNode->IsDerived(PX2::Node::TYPE), "relatParentOrEqualNode must be a Node."); relatParentOrEqualNode->AttachChild(triMesh); link = triMesh; } } for (i=0; i<(int)uMeshs.size(); i++) { delete0(uMeshs[i]); } if (needDel) { delete0(triObject); } return link; }
void BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSurface) { // We push groups for container layers if we need to, which always // are aligned in device space, so it doesn't really matter how we snap // containers. Matrix residual; Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface; if (!Extend3DContext() && !Is3DContextLeaf()) { // For 3D transform leaked from extended parent layer. idealTransform.ProjectTo2D(); } if (!idealTransform.CanDraw2D()) { if (!Extend3DContext() || (!idealTransform.Is2D() && Creates3DContextWithExtendingChildren())) { if (!Creates3DContextWithExtendingChildren()) { idealTransform.ProjectTo2D(); } mEffectiveTransform = idealTransform; ComputeEffectiveTransformsForChildren(Matrix4x4()); ComputeEffectiveTransformForMaskLayers(Matrix4x4()); mUseIntermediateSurface = true; return; } mEffectiveTransform = idealTransform; ComputeEffectiveTransformsForChildren(idealTransform); ComputeEffectiveTransformForMaskLayers(idealTransform); mUseIntermediateSurface = false; return; } // With 2D transform or extended 3D context. Layer* child = GetFirstChild(); bool hasSingleBlendingChild = false; if (!HasMultipleChildren() && child) { hasSingleBlendingChild = child->GetMixBlendMode() != CompositionOp::OP_OVER; } /* If we have a single childand it is not blending,, it can just inherit our opacity, * otherwise we need a PushGroup and we need to mark ourselves as using * an intermediate surface so our children don't inherit our opacity * via GetEffectiveOpacity. * Having a mask layer always forces our own push group * Having a blend mode also always forces our own push group */ mUseIntermediateSurface = GetMaskLayer() || GetForceIsolatedGroup() || (GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) || (GetEffectiveOpacity() != 1.0 && (HasMultipleChildren() || hasSingleBlendingChild)); if (!Extend3DContext()) { idealTransform.ProjectTo2D(); } mEffectiveTransform = !mUseIntermediateSurface ? idealTransform : SnapTransformTranslation(idealTransform, &residual); Matrix4x4 childTransformToSurface = (!mUseIntermediateSurface || (mUseIntermediateSurface && !Extend3DContext() /* 2D */)) ? idealTransform : Matrix4x4::From2D(residual); ComputeEffectiveTransformsForChildren(childTransformToSurface); ComputeEffectiveTransformForMaskLayers(aTransformToSurface); }