void GfxCanvasItem::moveToParent(GfxCanvasItem *p) { if(p == _parent || !p) return; // We (may) need to adjust x, y, scale and visible qreal x = globalX(); qreal y = globalY(); qreal s = globalScale(); qreal v = globalVisible(); setParent(p); if(x != globalX()) { this->x().setValue((x - _parent->globalX()) / _parent->globalScale()); } if(y != globalY()) { this->y().setValue((y - _parent->globalY()) / _parent->globalScale()); } if(s != globalScale()) { scale().setValue(s / _parent->globalScale()); } if(v != globalVisible()) { qreal pv = _parent->globalVisible(); if(pv) visible().setValue(v / pv); } }
void dgCollisionInstance::SetGlobalScale (const dgVector& scale) { // calculate current matrix dgMatrix matrix(dgGetIdentityMatrix()); matrix[0][0] = m_scale.m_x; matrix[1][1] = m_scale.m_y; matrix[2][2] = m_scale.m_z; matrix = m_aligmentMatrix * matrix * m_localMatrix; // extract the original local matrix dgMatrix transpose (matrix.Transpose()); dgVector globalScale (dgSqrt (transpose[0].DotProduct(transpose[0]).GetScalar()), dgSqrt (transpose[1].DotProduct(transpose[1]).GetScalar()), dgSqrt (transpose[2].DotProduct(transpose[2]).GetScalar()), dgFloat32 (1.0f)); dgVector invGlobalScale (dgFloat32 (1.0f) / globalScale.m_x, dgFloat32 (1.0f) / globalScale.m_y, dgFloat32 (1.0f) / globalScale.m_z, dgFloat32 (1.0f)); dgMatrix localMatrix (m_aligmentMatrix.Transpose() * m_localMatrix); localMatrix.m_posit = matrix.m_posit * invGlobalScale; dgAssert (localMatrix.m_posit.m_w == dgFloat32 (1.0f)); if ((dgAbs (scale[0] - scale[1]) < dgFloat32 (1.0e-4f)) && (dgAbs (scale[0] - scale[2]) < dgFloat32 (1.0e-4f))) { m_localMatrix = localMatrix; m_localMatrix.m_posit = m_localMatrix.m_posit * scale | dgVector::m_wOne; m_aligmentMatrix = dgGetIdentityMatrix(); SetScale (scale); } else { // create a new scale matrix localMatrix[0] = localMatrix[0] * scale; localMatrix[1] = localMatrix[1] * scale; localMatrix[2] = localMatrix[2] * scale; localMatrix[3] = localMatrix[3] * scale; localMatrix[3][3] = dgFloat32 (1.0f); // decompose into to align * scale * local localMatrix.PolarDecomposition (m_localMatrix, m_scale, m_aligmentMatrix); m_localMatrix = m_aligmentMatrix * m_localMatrix; m_aligmentMatrix = m_aligmentMatrix.Transpose(); dgAssert (m_localMatrix.TestOrthogonal()); dgAssert (m_aligmentMatrix.TestOrthogonal()); //dgMatrix xxx1 (dgGetIdentityMatrix()); //xxx1[0][0] = m_scale.m_x; //xxx1[1][1] = m_scale.m_y; //xxx1[2][2] = m_scale.m_z; //dgMatrix xxx (m_aligmentMatrix * xxx1 * m_localMatrix); bool isIdentity = true; for (dgInt32 i = 0; i < 3; i ++) { isIdentity &= dgAbs (m_aligmentMatrix[i][i] - dgFloat32 (1.0f)) < dgFloat32 (1.0e-5f); isIdentity &= dgAbs (m_aligmentMatrix[3][i]) < dgFloat32 (1.0e-5f); } m_scaleType = isIdentity ? m_nonUniform : m_global; m_maxScale = dgMax(m_scale[0], m_scale[1], m_scale[2]); m_invScale = dgVector (dgFloat32 (1.0f) / m_scale[0], dgFloat32 (1.0f) / m_scale[1], dgFloat32 (1.0f) / m_scale[2], dgFloat32 (0.0f)); } }
void Node::SetGlobalScale(const Vertex3& scale) { PNode parent = parent_.lock(); if (parent == nullptr) { SetScale(scale); } else { Vertex3 globalScale(parent->GetGlobalScale()); globalScale.x = 1 / globalScale.x; globalScale.y = 1 / globalScale.y; globalScale.z = 1 / globalScale.z; SetScale(globalScale * scale); } }