using System; using System.Collections; using Microsoft.DirectX; using FRB.Instructions; using Microsoft.DirectX.Direct3D; namespace FRB.Shapes { /// /// A set of points which represent a drawable closed polygon. /// /// /// This is a preliminary class which may be changed in future releases to add functionality and improve efficiency. /// public class LinePolygon { #region members internal Microsoft.DirectX.Direct3D.CustomVertex.PositionColored[] points; public int width; float X; float Y; float Z; float RotX; float RotY; float RotZ; Matrix RotationMatrix; private float Fade; private float TintRed; private float TintGreen; private float TintBlue; public float fadeRate; public float tintRedRate; public float tintBlueRate; public float tintGreenRate; public event lineCustomFunction customFunctions; private bool mVisible; // public FrbInstructionArray frbInstructionArray; #region members used to reduce garbage collection static float valueDifference; static Matrix changeMatrix; static Matrix newMatrix; static Vector4 v4 = new Vector4(0,0,0,1); #endregion #endregion #region properties public Vector3 this[int i] { get { return new Vector3(points[i].X, points[i].Y, points[i].Z); } set { points[i].X = value.X; points[i].Y = value.Y; points[i].Z = value.Z; } } public float x { get { return X; } set { valueDifference = value - X; if(valueDifference != 0) for(int i = 0; i < points.Length; i++) points[i].Position = new Vector3(points[i].X + valueDifference, points[i].Y, points[i].Z); X = value; } } public float y { get { return Y; } set { valueDifference = value - Y; if(valueDifference != 0) for(int i = 0; i < points.Length; i++) points[i].Position = new Vector3(points[i].X, points[i].Y + valueDifference, points[i].Z); Y = value; } } public float z { get { return Z; } set { valueDifference = value - Z; if(valueDifference != 0) for(int i = 0; i < points.Length; i++) points[i].Position = new Vector3(points[i].X, points[i].Y, points[i].Z + valueDifference); Z = value; } } public float rotX { get { return RotX; } set { CommonFunctions.RegulateAngle(ref value); valueDifference = value - RotX; if(valueDifference != 0) { newMatrix = Matrix.RotationX(value) * Matrix.RotationY(RotY) * Matrix.RotationZ(RotZ); changeMatrix = RotationMatrix; changeMatrix.Invert(); changeMatrix.Multiply(newMatrix); for(int i = 0; i < points.Length; i++) { v4.X = points[i].X - X; v4.Y = points[i].Y - Y; v4.Z = points[i].Z - Z; v4.Transform(changeMatrix); points[i].Position = new Vector3( v4.X + X, v4.Y + Y, v4.Z + Z); } RotationMatrix = newMatrix; RotX = value; } } } public float rotY { get { return RotY; } set { CommonFunctions.RegulateAngle(ref value); valueDifference = value - RotY; if(valueDifference != 0) { newMatrix = Matrix.RotationX(RotX) * Matrix.RotationY(value) * Matrix.RotationZ(RotZ); changeMatrix = RotationMatrix; changeMatrix.Invert(); changeMatrix.Multiply(newMatrix); for(int i = 0; i < points.Length; i++) { v4.X = points[i].X - X; v4.Y = points[i].Y - Y; v4.Z = points[i].Z - Z; v4.Transform(changeMatrix); points[i].Position = new Vector3( v4.X + X, v4.Y + Y, v4.Z + Z); } RotationMatrix = newMatrix; RotY = value; } } } public float rotZ { get { return RotZ; } set { CommonFunctions.RegulateAngle(ref value); valueDifference = value - RotZ; if(valueDifference != 0) { newMatrix = Matrix.RotationX(RotX) * Matrix.RotationY(RotY) * Matrix.RotationZ(value); changeMatrix = RotationMatrix; changeMatrix.Invert(); changeMatrix.Multiply(newMatrix); for(int i = 0; i < points.Length; i++) { v4.X = points[i].X - X; v4.Y = points[i].Y - Y; v4.Z = points[i].Z - Z; v4.Transform(changeMatrix); points[i].Position = new Vector3( v4.X + X, v4.Y + Y, v4.Z + Z); } RotationMatrix = newMatrix; RotZ = value; } } } public float fade { get { return Fade; } set { Fade = value; UpdateVertexColors(); } } public float tintRed { get { return TintRed; } set { TintRed = value; UpdateVertexColors(); } } public float tintGreen { get { return TintGreen; } set { TintGreen = value; UpdateVertexColors(); } } public float tintBlue { get { return TintBlue; } set { TintBlue = value; UpdateVertexColors(); } } public System.Drawing.Color color { get { return System.Drawing.Color.FromArgb((int)(255 - Fade),(int) TintRed, (int)TintGreen, (int)TintBlue); } set { Fade = 255 - value.A; TintRed = value.R; TintGreen = value.G; TintBlue = value.B; this.UpdateVertexColors(); } } public bool visible { get { return mVisible; } set { mVisible = value; } } #endregion #region methods public LinePolygon() { width = 1; X = Y = Z = 0; RotationMatrix = Matrix.Identity; // make the shape visible by default. visible = true; // this.frbInstructionArray = new FRB.Collections.FrbInstructionArray(); } internal void m_customFunction(ShapeManager shaMan) { if(customFunctions != null) customFunctions(this, shaMan); } public bool IsPointInside(Math2D.Point P) { bool b = false; for (int i = 0, j = this.points.Length - 1; i < this.points.Length; j = i++) { if ((((points[i].Y <= P.y) && (P.y < points[j].Y)) || ((points[j].Y <= P.y) && (P.y < points[i].Y))) && (P.x < (points[j].X - points[i].X) * (P.y - points[i].Y) / (points[j].Y - points[i].Y) + points[i].X)) b = !b; } return b; } public void ScaleBy(float scaleValue) { for (int i = 0; i < points.Length; i++) { points[i].X = this.x + (points[i].X - this.x) * scaleValue; points[i].Y = this.y + (points[i].Y - this.y) * scaleValue; points[i].Z = this.z + (points[i].Z - this.z) * scaleValue; } } public void SetPoint(int index, Microsoft.DirectX.Vector3 pointToSet) { points[index].Position = pointToSet; } /// /// Sets the object's points and calculates the center point as an average of all passed points. /// /// The points to set. public void SetPoints(Microsoft.DirectX.Vector3[] pointsToSet) { this.points = new CustomVertex.PositionColored[pointsToSet.Length]; // for(int i = 0; i < pointsToSet.Length; i++) { points[i].Position = pointsToSet[i]; } TintRed = 255; TintGreen = 255; TintBlue = 255; Fade = 0; this.UpdateVertexColors(); float xSum = 0; float ySum = 0; float zSum = 0; foreach(CustomVertex.PositionColored p in points) { xSum += p.X; ySum += p.Y; zSum += p.Z; } X = xSum/((float)points.Length); Y = ySum/((float)points.Length); Z = zSum/((float)points.Length); } /// /// /// /// /// Remeber to call the AttachablePoly's UpdateDependenciesFull if it is not being called automatically /// in collision methods so that the LinePolygon is drawn correctly. /// /// public void SetPoints(Math2D.AttachablePoly ap) { Microsoft.DirectX.Vector3[] pointsToSet = new Vector3[ap.p.Length]; for(int i = 0; i < ap.p.Length; i++) { pointsToSet[i] = new Vector3((float)ap.p[i].x, (float)ap.p[i].y, 0); } this.SetPoints(pointsToSet); } /// /// Sets the LinePolygon's center (x, y, and z) without moving any points. /// /// The absolute x to set for the new center. /// The absolute y to set for the new center. /// The absolute z to set for the new center. public void SetCenter(float x, float y, float z) { X = x; Y = y; Z = z; } /// /// Sets the LinePolygon's rotation values without moving any points. /// /// The absolute rotation about the xAxis to set. /// The absolute rotation about the yAxis to set. /// The absolute rotation about the zAxis to set. public void SetRotation(float rotX, float rotY, float rotZ) { RotX = rotX; RotY = rotY; RotZ = rotZ; } public void TimedActivity(float secondDifference) { Fade += fadeRate * secondDifference; TintRed += tintRedRate * secondDifference; TintGreen += tintGreenRate * secondDifference; TintBlue += tintBlueRate * secondDifference; /* If the fadeRate is 0,the vertex colors and alphas won't be updated. When * the fadeRate makes the fade equal either 0 or 255, then the fadeRate is set to 0. * Since the FadeRate is set to 0, the UpdateVertexColors won't be drawn so we have to * explicitly call it in the if statements where we set the fade to 0. */ if(Fade < 0) { fadeRate = 0; Fade = 0; this.UpdateVertexColors(); } if(Fade > 255) { fadeRate = 0; Fade = 255; this.UpdateVertexColors(); } if(fadeRate != 0 || tintRedRate != 0 || tintGreenRate != 0 || tintBlueRate != 0) this.UpdateVertexColors(); } private void UpdateVertexColors() { if(points == null) return; int color = System.Drawing.Color.FromArgb((int)(255-Fade), (int)TintRed, (int)TintGreen, (int)TintBlue).ToArgb(); for(int i = 0; i < points.Length; i++) this.points[i].Color = color; } #endregion } }