port from perforce
This commit is contained in:
306
aiwaz/Backup/Aiwaz.Resources/Transformation.cs
Normal file
306
aiwaz/Backup/Aiwaz.Resources/Transformation.cs
Normal file
@@ -0,0 +1,306 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Aiwaz.Contracts;
|
||||
using Aiwaz.Resources.Attributes;
|
||||
|
||||
namespace Aiwaz.Resources
|
||||
{
|
||||
public class TransformationBindings : ICreationParams
|
||||
{
|
||||
public string WorldMatrixSemanticName;
|
||||
public string LocalMatrixSemanticName;
|
||||
|
||||
public string WorldPositionSemanticName;
|
||||
public string LocalPositionSemanticName;
|
||||
|
||||
public string WorldDirectionSemanticName;
|
||||
public string LocalDirectionSemanticName;
|
||||
|
||||
public string WorldUpDirectionSemanticName;
|
||||
public string LocalUpDirectionSemanticName;
|
||||
|
||||
public string WorldRightDirectionSemanticName;
|
||||
public string LocalRightDirectionSemanticName;
|
||||
}
|
||||
|
||||
[CreationParameters("Default transformation")]
|
||||
public class DefaultTransformationBindings : TransformationBindings
|
||||
{
|
||||
public DefaultTransformationBindings()
|
||||
{
|
||||
WorldMatrixSemanticName = "WorldMatrix";
|
||||
LocalMatrixSemanticName = "LocalMatrix";
|
||||
WorldPositionSemanticName = "WorldPosition";
|
||||
LocalPositionSemanticName = "LocalPosition";
|
||||
WorldDirectionSemanticName = "WorldDirection";
|
||||
LocalDirectionSemanticName = "LocalDirection";
|
||||
WorldUpDirectionSemanticName = "WorldUpDirection";
|
||||
LocalUpDirectionSemanticName = "LocalUpDirection";
|
||||
WorldRightDirectionSemanticName = "WorldUpDirection";
|
||||
LocalRightDirectionSemanticName = "LocalUpDirection";
|
||||
}
|
||||
}
|
||||
|
||||
[CreationParameters("Camera transformation")]
|
||||
public class CameraTransformationBindings : TransformationBindings
|
||||
{
|
||||
public CameraTransformationBindings()
|
||||
{
|
||||
WorldPositionSemanticName = "CamPos";
|
||||
WorldDirectionSemanticName = "CamDir";
|
||||
}
|
||||
}
|
||||
|
||||
[AiwazResource("Transformation", "Common transformations for a shader and geometry buffers like position, scale and rotation.")]
|
||||
public class Transformation : ShaderParameterSet, IUpdatable
|
||||
{
|
||||
#region ITransformation Members
|
||||
|
||||
Reference worldMatrixRef = new Reference(new SlimDX.Matrix());
|
||||
Reference worldPositionRef = new Reference(new SlimDX.Vector3());
|
||||
Reference worldDirectionRef = new Reference(new SlimDX.Vector3());
|
||||
Reference worldUpDirectionRef = new Reference(new SlimDX.Vector3());
|
||||
Reference worldRightDirectionRef = new Reference(new SlimDX.Vector3());
|
||||
|
||||
Reference localMatrixRef = new Reference(new SlimDX.Matrix());
|
||||
Reference localPositionRef = new Reference(new SlimDX.Vector3());
|
||||
Reference localDirectionRef = new Reference(new SlimDX.Vector3());
|
||||
Reference localUpDirectionRef = new Reference(new SlimDX.Vector3());
|
||||
Reference localRightDirectionRef = new Reference(new SlimDX.Vector3());
|
||||
|
||||
private TransformationBindings transformationBindings;
|
||||
private SlimDX.Vector3 lastKnownYawPitchRoll;
|
||||
private SlimDX.Quaternion localRotation;
|
||||
private SlimDX.Vector3 localScale;
|
||||
private Transformation transformationParent;
|
||||
private List<Transformation> transformations = new List<Transformation>();
|
||||
|
||||
private Transformation()
|
||||
: base(5)
|
||||
{
|
||||
}
|
||||
|
||||
private Transformation(TransformationBindings transformationBindings)
|
||||
: this()
|
||||
{
|
||||
this.WorldScale = this.LocalScale = new SlimDX.Vector3(1.0f, 1.0f, 1.0f);
|
||||
this.LocalDirection = this.WorldDirection = new SlimDX.Vector3(0.0f, 0.0f, 1.0f);
|
||||
this.LocalUpDirection = this.WorldUpDirection = new SlimDX.Vector3(0.0f, 1.0f, 0.0f);
|
||||
this.LocalRightDirection = this.WorldRightDirection = new SlimDX.Vector3(1.0f, 0.0f, 0.0f);
|
||||
this.TransformationBindings = transformationBindings;
|
||||
}
|
||||
|
||||
public Transformation(DefaultTransformationBindings transformationBindings)
|
||||
: this((TransformationBindings)transformationBindings)
|
||||
{
|
||||
}
|
||||
|
||||
public Transformation(CameraTransformationBindings transformationBindings)
|
||||
: this((TransformationBindings)transformationBindings)
|
||||
{
|
||||
}
|
||||
|
||||
public TransformationBindings TransformationBindings
|
||||
{
|
||||
get { return transformationBindings; }
|
||||
set
|
||||
{
|
||||
transformationBindings = value;
|
||||
|
||||
baseShaderParameterSet.RemoveAllShaderParameters();
|
||||
this.RecreateAllShaderParameters();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SlimDX.Vector3 LocalPosition
|
||||
{
|
||||
get { return (SlimDX.Vector3)localPositionRef.RawValue; }
|
||||
set
|
||||
{
|
||||
localPositionRef.RawValue = value;
|
||||
WantsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public SlimDX.Vector3 WorldPosition { get { return (SlimDX.Vector3)worldPositionRef.RawValue; } protected set { worldPositionRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Vector3 LocalRotationYPR
|
||||
{
|
||||
get
|
||||
{
|
||||
return lastKnownYawPitchRoll;
|
||||
}
|
||||
set
|
||||
{
|
||||
lastKnownYawPitchRoll = value;
|
||||
LocalRotation = SlimDX.Quaternion.RotationYawPitchRoll(value.X, value.Y, value.Z);
|
||||
|
||||
WantsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public SlimDX.Quaternion LocalRotation
|
||||
{
|
||||
get { return localRotation; }
|
||||
set
|
||||
{
|
||||
localRotation = value;
|
||||
WantsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public SlimDX.Quaternion WorldRotation { get; protected set; }
|
||||
|
||||
public SlimDX.Vector3 LocalDirection { get { return (SlimDX.Vector3)localDirectionRef.RawValue; } protected set { localDirectionRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Vector3 WorldDirection { get { return (SlimDX.Vector3)worldDirectionRef.RawValue; } protected set { worldDirectionRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Vector3 LocalUpDirection { get { return (SlimDX.Vector3)localUpDirectionRef.RawValue; } protected set { localUpDirectionRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Vector3 WorldUpDirection { get { return (SlimDX.Vector3)worldUpDirectionRef.RawValue; } protected set { worldUpDirectionRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Vector3 LocalRightDirection { get { return (SlimDX.Vector3)localRightDirectionRef.RawValue; } protected set { localRightDirectionRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Vector3 WorldRightDirection { get { return (SlimDX.Vector3)worldRightDirectionRef.RawValue; } protected set { worldRightDirectionRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Vector3 LocalScale
|
||||
{
|
||||
get { return localScale; }
|
||||
set
|
||||
{
|
||||
localScale = value;
|
||||
WantsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public SlimDX.Vector3 WorldScale { get; protected set; }
|
||||
|
||||
public SlimDX.Matrix WorldMatrix { get { return (SlimDX.Matrix)worldMatrixRef.RawValue; } protected set { worldMatrixRef.RawValue = value; } }
|
||||
|
||||
public SlimDX.Matrix LocalMatrix { get { return (SlimDX.Matrix)localMatrixRef.RawValue; } protected set { localMatrixRef.RawValue = value; } }
|
||||
|
||||
public Transformation TransformationParent
|
||||
{
|
||||
get { return transformationParent; }
|
||||
set
|
||||
{
|
||||
var oldTransformationParent = transformationParent;
|
||||
transformationParent = value;
|
||||
WantsUpdate = true;
|
||||
|
||||
if (oldTransformationParent != null)
|
||||
oldTransformationParent.RemoveTransformation(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<Transformation> Transformations { get { return transformations; } }
|
||||
|
||||
public void AddTransformation(Transformation transformation)
|
||||
{
|
||||
if (!transformations.Contains(transformation))
|
||||
{
|
||||
transformation.TransformationParent = this;
|
||||
transformations.Add(transformation);
|
||||
WantsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveTransformation(Transformation transformation)
|
||||
{
|
||||
if (transformations.Remove(transformation))
|
||||
transformation.TransformationParent = null;
|
||||
}
|
||||
|
||||
protected virtual void RecreateAllShaderParameters()
|
||||
{
|
||||
if (transformationBindings == null)
|
||||
return;
|
||||
if (!string.IsNullOrEmpty(transformationBindings.WorldMatrixSemanticName))
|
||||
this.SetParameter(transformationBindings.WorldMatrixSemanticName, worldMatrixRef, ParameterBindType.BindBySemantic);
|
||||
if (!string.IsNullOrEmpty(transformationBindings.LocalMatrixSemanticName))
|
||||
this.SetParameter(transformationBindings.LocalMatrixSemanticName, localMatrixRef, ParameterBindType.BindBySemantic);
|
||||
|
||||
if (!string.IsNullOrEmpty(transformationBindings.WorldPositionSemanticName))
|
||||
this.SetParameter(transformationBindings.WorldPositionSemanticName, worldPositionRef, ParameterBindType.BindBySemantic);
|
||||
if (!string.IsNullOrEmpty(transformationBindings.LocalPositionSemanticName))
|
||||
this.SetParameter(transformationBindings.LocalPositionSemanticName, localPositionRef, ParameterBindType.BindBySemantic);
|
||||
|
||||
if (!string.IsNullOrEmpty(transformationBindings.WorldDirectionSemanticName))
|
||||
this.SetParameter(transformationBindings.WorldDirectionSemanticName, worldDirectionRef, ParameterBindType.BindBySemantic);
|
||||
if (!string.IsNullOrEmpty(transformationBindings.LocalDirectionSemanticName))
|
||||
this.SetParameter(transformationBindings.LocalDirectionSemanticName, localDirectionRef, ParameterBindType.BindBySemantic);
|
||||
|
||||
if (!string.IsNullOrEmpty(transformationBindings.WorldUpDirectionSemanticName))
|
||||
this.SetParameter(transformationBindings.WorldUpDirectionSemanticName, worldUpDirectionRef, ParameterBindType.BindBySemantic);
|
||||
if (!string.IsNullOrEmpty(transformationBindings.LocalUpDirectionSemanticName))
|
||||
this.SetParameter(transformationBindings.LocalUpDirectionSemanticName, localUpDirectionRef, ParameterBindType.BindBySemantic);
|
||||
|
||||
if (!string.IsNullOrEmpty(transformationBindings.WorldRightDirectionSemanticName))
|
||||
this.SetParameter(transformationBindings.WorldRightDirectionSemanticName, worldRightDirectionRef, ParameterBindType.BindBySemantic);
|
||||
if (!string.IsNullOrEmpty(transformationBindings.LocalRightDirectionSemanticName))
|
||||
this.SetParameter(transformationBindings.LocalRightDirectionSemanticName, localRightDirectionRef, ParameterBindType.BindBySemantic);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IUpdatable Members
|
||||
|
||||
public virtual void Update(bool forceUpdate)
|
||||
{
|
||||
if (!WantsUpdate && !forceUpdate)
|
||||
return;
|
||||
|
||||
WantsUpdate = false;
|
||||
|
||||
var localMatrix = SlimDX.Matrix.Transformation(SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, localScale, SlimDX.Vector3.Zero, localRotation, this.LocalPosition);
|
||||
|
||||
var direction = new SlimDX.Vector3(0.0f, 0.0f, 1.0f);
|
||||
var upDirection = new SlimDX.Vector3(0.0f, 1.0f, 0.0f);
|
||||
var rightDirection = new SlimDX.Vector3(1.0f, 0.0f, 0.0f);
|
||||
|
||||
{
|
||||
var rotMat = SlimDX.Matrix.RotationQuaternion(localRotation);
|
||||
LocalDirection = SlimDX.Vector3.TransformNormal(direction, rotMat);
|
||||
LocalUpDirection = SlimDX.Vector3.TransformNormal(upDirection, rotMat);
|
||||
LocalRightDirection = SlimDX.Vector3.TransformNormal(rightDirection, rotMat);
|
||||
}
|
||||
|
||||
WorldMatrix = localMatrix;
|
||||
// stack parent matrix
|
||||
if (transformationParent != null)
|
||||
WorldMatrix = localMatrix * transformationParent.WorldMatrix;
|
||||
|
||||
// extract world related data
|
||||
SlimDX.Vector3 tmpScale;
|
||||
SlimDX.Vector3 tmpPos;
|
||||
SlimDX.Quaternion tmpRot;
|
||||
WorldMatrix.Decompose(out tmpScale, out tmpRot, out tmpPos);
|
||||
WorldPosition = tmpPos;
|
||||
WorldRotation = tmpRot;
|
||||
WorldScale = tmpScale;
|
||||
{
|
||||
var rotMat = SlimDX.Matrix.RotationQuaternion(WorldRotation);
|
||||
WorldDirection = SlimDX.Vector3.TransformNormal(direction, rotMat);
|
||||
WorldUpDirection = SlimDX.Vector3.TransformNormal(upDirection, rotMat);
|
||||
WorldRightDirection = SlimDX.Vector3.TransformNormal(rightDirection, rotMat);
|
||||
}
|
||||
|
||||
// update following transformations
|
||||
foreach (var transformation in transformations)
|
||||
if (transformation is IUpdatable)
|
||||
{
|
||||
var updatable = transformation as IUpdatable;
|
||||
if (updatable != null && (updatable.WantsUpdate || forceUpdate))
|
||||
updatable.Update(forceUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
public bool WantsUpdate { get; protected set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user