-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding Translation, Scale, Rotation, and Transform constraints.
- Loading branch information
1 parent
89ca40d
commit 2e7e871
Showing
10 changed files
with
780 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
using System; | ||
using System.IO; | ||
using System.Collections.Generic; | ||
using Nima.Math2D; | ||
|
||
namespace Nima | ||
{ | ||
public abstract class ActorAxisConstraint : ActorTargetedConstraint | ||
{ | ||
protected bool m_CopyX; | ||
protected bool m_CopyY; | ||
protected float m_ScaleX; | ||
protected float m_ScaleY; | ||
protected bool m_EnableMinX; | ||
protected bool m_EnableMinY; | ||
protected bool m_EnableMaxX; | ||
protected bool m_EnableMaxY; | ||
protected float m_MaxX; | ||
protected float m_MaxY; | ||
protected float m_MinX; | ||
protected float m_MinY; | ||
protected bool m_Offset; | ||
protected TransformSpace m_SourceSpace; | ||
protected TransformSpace m_DestSpace; | ||
protected TransformSpace m_MinMaxSpace; | ||
|
||
public ActorAxisConstraint() | ||
{ | ||
m_CopyX = false; | ||
m_CopyY = false; | ||
m_ScaleX = 1.0f; | ||
m_ScaleY = 1.0f; | ||
m_EnableMinX = false; | ||
m_EnableMinY = false; | ||
m_EnableMaxX = false; | ||
m_EnableMaxY = false; | ||
m_MinX = 0.0f; | ||
m_MinY = 0.0f; | ||
m_MaxX = 0.0f; | ||
m_MaxY = 0.0f; | ||
m_Offset = false; | ||
m_SourceSpace = TransformSpace.World; | ||
m_DestSpace = TransformSpace.World; | ||
m_MinMaxSpace = TransformSpace.World; | ||
} | ||
|
||
public override void OnDirty(byte dirt) | ||
{ | ||
MarkDirty(); | ||
} | ||
|
||
public static ActorAxisConstraint Read(Actor actor, BinaryReader reader, ActorAxisConstraint component) | ||
{ | ||
ActorTargetedConstraint.Read(actor, reader, component); | ||
|
||
if((component.m_CopyX = reader.ReadByte() == 1)) | ||
{ | ||
component.m_ScaleX = reader.ReadSingle(); | ||
} | ||
if((component.m_EnableMinX = reader.ReadByte() == 1)) | ||
{ | ||
component.m_MinX = reader.ReadSingle(); | ||
} | ||
if((component.m_EnableMaxX = reader.ReadByte() == 1)) | ||
{ | ||
component.m_MaxX = reader.ReadSingle(); | ||
} | ||
|
||
// Y Axis | ||
if((component.m_CopyY = reader.ReadByte() == 1)) | ||
{ | ||
component.m_ScaleY = reader.ReadSingle(); | ||
} | ||
if((component.m_EnableMinY = reader.ReadByte() == 1)) | ||
{ | ||
component.m_MinY = reader.ReadSingle(); | ||
} | ||
if((component.m_EnableMaxY = reader.ReadByte() == 1)) | ||
{ | ||
component.m_MaxY = reader.ReadSingle(); | ||
} | ||
|
||
component.m_Offset = reader.ReadByte() == 1; | ||
component.m_SourceSpace = (TransformSpace)reader.ReadByte(); | ||
component.m_DestSpace = (TransformSpace)reader.ReadByte(); | ||
component.m_MinMaxSpace = (TransformSpace)reader.ReadByte(); | ||
|
||
return component; | ||
} | ||
|
||
public void Copy(ActorAxisConstraint node, Actor resetActor) | ||
{ | ||
base.Copy(node, resetActor); | ||
|
||
m_CopyX = node.m_CopyX; | ||
m_CopyY = node.m_CopyY; | ||
m_ScaleX = node.m_ScaleX; | ||
m_ScaleY = node.m_ScaleY; | ||
m_EnableMinX = node.m_EnableMinX; | ||
m_EnableMinY = node.m_EnableMinY; | ||
m_EnableMaxX = node.m_EnableMaxX; | ||
m_EnableMaxY = node.m_EnableMaxY; | ||
m_MinX = node.m_MinX; | ||
m_MinY = node.m_MinY; | ||
m_MaxX = node.m_MaxX; | ||
m_MaxY = node.m_MaxY; | ||
m_Offset = node.m_Offset; | ||
m_SourceSpace = node.m_SourceSpace; | ||
m_DestSpace = node.m_DestSpace; | ||
m_MinMaxSpace = node.m_MinMaxSpace; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
using System; | ||
using System.IO; | ||
using System.Collections.Generic; | ||
using Nima.Math2D; | ||
|
||
namespace Nima | ||
{ | ||
public class ActorRotationConstraint : ActorTargetedConstraint | ||
{ | ||
const float PI2 = (float)(Math.PI*2.0); | ||
|
||
protected bool m_Copy; | ||
protected float m_Scale; | ||
protected bool m_EnableMin; | ||
protected bool m_EnableMax; | ||
protected float m_Max; | ||
protected float m_Min; | ||
protected bool m_Offset; | ||
protected TransformSpace m_SourceSpace; | ||
protected TransformSpace m_DestSpace; | ||
protected TransformSpace m_MinMaxSpace; | ||
TransformComponents m_ComponentsA; | ||
TransformComponents m_ComponentsB; | ||
|
||
public ActorRotationConstraint() | ||
{ | ||
m_Copy = false; | ||
m_Scale = 1.0f; | ||
m_EnableMin = false; | ||
m_EnableMax = false; | ||
m_Min = 0.0f; | ||
m_Max = 0.0f; | ||
m_Offset = false; | ||
m_SourceSpace = TransformSpace.World; | ||
m_DestSpace = TransformSpace.World; | ||
m_MinMaxSpace = TransformSpace.World; | ||
m_ComponentsA = new TransformComponents(); | ||
m_ComponentsB = new TransformComponents(); | ||
} | ||
|
||
public override void OnDirty(byte dirt) | ||
{ | ||
MarkDirty(); | ||
} | ||
|
||
public static ActorRotationConstraint Read(Actor actor, BinaryReader reader, ActorRotationConstraint component = null) | ||
{ | ||
if(component == null) | ||
{ | ||
component = new ActorRotationConstraint(); | ||
} | ||
ActorTargetedConstraint.Read(actor, reader, component); | ||
|
||
if((component.m_Copy = reader.ReadByte() == 1)) | ||
{ | ||
component.m_Scale = reader.ReadSingle(); | ||
} | ||
if((component.m_EnableMin = reader.ReadByte() == 1)) | ||
{ | ||
component.m_Min = reader.ReadSingle(); | ||
} | ||
if((component.m_EnableMax = reader.ReadByte() == 1)) | ||
{ | ||
component.m_Max = reader.ReadSingle(); | ||
} | ||
|
||
component.m_Offset = reader.ReadByte() == 1; | ||
component.m_SourceSpace = (TransformSpace)reader.ReadByte(); | ||
component.m_DestSpace = (TransformSpace)reader.ReadByte(); | ||
component.m_MinMaxSpace = (TransformSpace)reader.ReadByte(); | ||
|
||
return component; | ||
} | ||
|
||
public void Copy(ActorRotationConstraint node, Actor resetActor) | ||
{ | ||
base.Copy(node, resetActor); | ||
|
||
m_Copy = node.m_Copy; | ||
m_Scale = node.m_Scale; | ||
m_EnableMin = node.m_EnableMin; | ||
m_EnableMax = node.m_EnableMax; | ||
m_Min = node.m_Min; | ||
m_Max = node.m_Max; | ||
|
||
m_Offset = node.m_Offset; | ||
m_SourceSpace = node.m_SourceSpace; | ||
m_DestSpace = node.m_DestSpace; | ||
m_MinMaxSpace = node.m_MinMaxSpace; | ||
} | ||
|
||
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); | ||
} | ||
|
||
public override ActorComponent MakeInstance(Actor resetActor) | ||
{ | ||
ActorRotationConstraint instance = new ActorRotationConstraint(); | ||
instance.Copy(this, resetActor); | ||
return instance; | ||
} | ||
} | ||
} |
Oops, something went wrong.