using System;
using UnityEngine;
using Debug = System.Diagnostics.Debug;
namespace LibNoise.Operator
{
///
/// Provides a noise module that rotates the input value around the origin before
/// returning the output value from a source module. [OPERATOR]
///
public class Rotate : ModuleBase
{
#region Fields
private double _x;
private double _x1Matrix;
private double _x2Matrix;
private double _x3Matrix;
private double _y;
private double _y1Matrix;
private double _y2Matrix;
private double _y3Matrix;
private double _z;
private double _z1Matrix;
private double _z2Matrix;
private double _z3Matrix;
#endregion
#region Constructors
///
/// Initializes a new instance of Rotate.
///
public Rotate()
: base(1)
{
SetAngles(0.0, 0.0, 0.0);
}
///
/// Initializes a new instance of Rotate.
///
/// The input module.
public Rotate(ModuleBase input)
: base(1)
{
Modules[0] = input;
}
///
/// Initializes a new instance of Rotate.
///
/// The rotation around the x-axis.
/// The rotation around the y-axis.
/// The rotation around the z-axis.
/// The input module.
public Rotate(double x, double y, double z, ModuleBase input)
: base(1)
{
Modules[0] = input;
SetAngles(x, y, z);
}
#endregion
#region Properties
///
/// Gets or sets the rotation around the x-axis in degree.
///
public double X
{
get { return _x; }
set { SetAngles(value, _y, _z); }
}
///
/// Gets or sets the rotation around the y-axis in degree.
///
public double Y
{
get { return _y; }
set { SetAngles(_x, value, _z); }
}
///
/// Gets or sets the rotation around the z-axis in degree.
///
public double Z
{
get { return _x; }
set { SetAngles(_x, _y, value); }
}
#endregion
#region Methods
///
/// Sets the rotation angles.
///
/// The rotation around the x-axis.
/// The rotation around the y-axis.
/// The rotation around the z-axis.
private void SetAngles(double x, double y, double z)
{
var xc = Math.Cos(x * Mathf.Deg2Rad);
var yc = Math.Cos(y * Mathf.Deg2Rad);
var zc = Math.Cos(z * Mathf.Deg2Rad);
var xs = Math.Sin(x * Mathf.Deg2Rad);
var ys = Math.Sin(y * Mathf.Deg2Rad);
var zs = Math.Sin(z * Mathf.Deg2Rad);
_x1Matrix = ys * xs * zs + yc * zc;
_y1Matrix = xc * zs;
_z1Matrix = ys * zc - yc * xs * zs;
_x2Matrix = ys * xs * zc - yc * zs;
_y2Matrix = xc * zc;
_z2Matrix = -yc * xs * zc - ys * zs;
_x3Matrix = -ys * xc;
_y3Matrix = xs;
_z3Matrix = yc * xc;
_x = x;
_y = y;
_z = z;
}
#endregion
#region ModuleBase Members
///
/// Returns the output value for the given input coordinates.
///
/// The input coordinate on the x-axis.
/// The input coordinate on the y-axis.
/// The input coordinate on the z-axis.
/// The resulting output value.
public override double GetValue(double x, double y, double z)
{
Debug.Assert(Modules[0] != null);
var nx = (_x1Matrix * x) + (_y1Matrix * y) + (_z1Matrix * z);
var ny = (_x2Matrix * x) + (_y2Matrix * y) + (_z2Matrix * z);
var nz = (_x3Matrix * x) + (_y3Matrix * y) + (_z3Matrix * z);
return Modules[0].GetValue(nx, ny, nz);
}
#endregion
}
}