public void Copy(ActorImage node, Actor resetActor) { base.Copy(node, resetActor); m_DrawOrder = node.m_DrawOrder; m_BlendMode = node.m_BlendMode; m_TextureIndex = node.m_TextureIndex; m_VertexCount = node.m_VertexCount; m_TriangleCount = node.m_TriangleCount; m_Vertices = node.m_Vertices; m_Triangles = node.m_Triangles; if (node.m_AnimationDeformedVertices != null) { m_AnimationDeformedVertices = (float[])node.m_AnimationDeformedVertices.Clone(); } if (node.m_BoneConnections != null) { m_BoneConnections = new BoneConnection[node.m_BoneConnections.Length]; for (int i = 0; i < node.m_BoneConnections.Length; i++) { BoneConnection bc = new BoneConnection(); bc.m_BoneIdx = node.m_BoneConnections[i].m_BoneIdx; Mat2D.Copy(bc.m_Bind, node.m_BoneConnections[i].m_Bind); Mat2D.Copy(bc.m_InverseBind, node.m_BoneConnections[i].m_InverseBind); m_BoneConnections[i] = bc; } } }
/** * parentMat: null -> no change * same pointer -> parent transform changed * diff pointer -> parent changed */ public static void Draw(Group *self, float *parentMat, bool isParentTransformDirty) { var childLst = &self->childLst; int childCount = childLst->count; void **childArr = childLst->arr; // sort by depth if any child depth is changed for (int i = 0; i < childCount; i += 1) { if (Node.IsDepthDirty(childArr[i])) { Algo.MergeSort(childArr, childCount, Node.DepthCmp); break; } } float *mat = self->mat; float *concatMat = self->concatMat; bool isTransformDirty = self->isTransformDirty; if (isTransformDirty) { self->isTransformDirty = false; Mat2D.FromScalingRotationTranslation(mat, self->pos, self->scl, self->rot); } if (isParentTransformDirty) { self->parentMat = parentMat; } if (isTransformDirty || isParentTransformDirty) { isParentTransformDirty = true; if (parentMat == null) { Mat2D.Copy(concatMat, mat); } else { Mat2D.Mul(concatMat, parentMat, mat); } } for (int i = 0; i < childCount; i += 1) { Node.Draw(childArr[i], concatMat, isParentTransformDirty); } }
private void UpdateWorldTransform() { m_RenderOpacity = m_Opacity; if (m_Parent != null) { m_RenderCollapsed = m_IsCollapsedVisibility || m_Parent.m_RenderCollapsed; m_RenderOpacity *= m_Parent.m_RenderOpacity; if (!m_OverrideWorldTransform) { Mat2D.Multiply(m_WorldTransform, m_Parent.m_WorldTransform, m_Transform); } } else { Mat2D.Copy(m_WorldTransform, m_Transform); } }
public override void Constrain(ActorNode node) { ActorNode target = m_Target as ActorNode; ActorNode grandParent = m_Parent.Parent; Mat2D transformA = m_Parent.WorldTransform; Mat2D transformB = new Mat2D(); Mat2D.Decompose(transformA, m_ComponentsA); if (target == null) { Mat2D.Copy(transformB, transformA); m_ComponentsB[0] = m_ComponentsA[0]; m_ComponentsB[1] = m_ComponentsA[1]; m_ComponentsB[2] = m_ComponentsA[2]; m_ComponentsB[3] = m_ComponentsA[3]; m_ComponentsB[4] = m_ComponentsA[4]; m_ComponentsB[5] = m_ComponentsA[5]; } else { Mat2D.Copy(transformB, target.WorldTransform); if (m_SourceSpace == TransformSpace.Local) { ActorNode sourceGrandParent = target.Parent; if (sourceGrandParent != null) { Mat2D inverse = new Mat2D(); if (!Mat2D.Invert(inverse, sourceGrandParent.WorldTransform)) { return; } Mat2D.Multiply(transformB, inverse, transformB); } } Mat2D.Decompose(transformB, m_ComponentsB); if (!m_Copy) { m_ComponentsB.Rotation = m_DestSpace == TransformSpace.Local ? 1.0f : m_ComponentsA.Rotation; } else { m_ComponentsB.Rotation *= m_Scale; if (m_Offset) { m_ComponentsB.Rotation += m_Parent.Rotation; } } if (m_DestSpace == TransformSpace.Local) { // Destination space is in parent transform coordinates. // Recompose the parent local transform and get it in world, then decompose the world for interpolation. if (grandParent != null) { Mat2D.Compose(transformB, m_ComponentsB); Mat2D.Multiply(transformB, grandParent.WorldTransform, transformB); Mat2D.Decompose(transformB, m_ComponentsB); } } } bool clampLocal = m_MinMaxSpace == TransformSpace.Local && grandParent != null; if (clampLocal) { // Apply min max in local space, so transform to local coordinates first. Mat2D.Compose(transformB, m_ComponentsB); Mat2D inverse = new Mat2D(); if (!Mat2D.Invert(inverse, grandParent.WorldTransform)) { return; } Mat2D.Multiply(transformB, inverse, transformB); Mat2D.Decompose(transformB, m_ComponentsB); } if (m_EnableMax && m_ComponentsB.Rotation > m_Max) { m_ComponentsB.Rotation = m_Max; } if (m_EnableMin && m_ComponentsB.Rotation < m_Min) { m_ComponentsB.Rotation = m_Min; } if (clampLocal) { // Transform back to world. Mat2D.Compose(transformB, m_ComponentsB); Mat2D.Multiply(transformB, grandParent.WorldTransform, transformB); Mat2D.Decompose(transformB, m_ComponentsB); } float angleA = m_ComponentsA.Rotation % PI2; float angleB = m_ComponentsB.Rotation % PI2; float diff = angleB - angleA; if (diff > Math.PI) { diff -= PI2; } else if (diff < -Math.PI) { diff += PI2; } float ti = 1.0f - m_Strength; m_ComponentsB.Rotation = m_ComponentsA.Rotation + diff * m_Strength; m_ComponentsB.X = m_ComponentsA.X; m_ComponentsB.Y = m_ComponentsA.Y; m_ComponentsB.ScaleX = m_ComponentsA.ScaleX; m_ComponentsB.ScaleY = m_ComponentsA.ScaleY; m_ComponentsB.Skew = m_ComponentsA.Skew; Mat2D.Compose(m_Parent.WorldTransform, m_ComponentsB); }