internal static int CreateAnimatedWorldObject(AnimatedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) { Array.Resize<AnimatedWorldObject>(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1); } World.Transformation FinalTransformation = new World.Transformation(BaseTransformation, AuxTransformation); AnimatedWorldObjects[a] = new AnimatedWorldObject(); AnimatedWorldObjects[a].Position = Position; AnimatedWorldObjects[a].Direction = FinalTransformation.Z; AnimatedWorldObjects[a].Up = FinalTransformation.Y; AnimatedWorldObjects[a].Side = FinalTransformation.X; AnimatedWorldObjects[a].Object = Prototype.Clone(); AnimatedWorldObjects[a].Object.ObjectIndex = CreateDynamicObject(); AnimatedWorldObjects[a].SectionIndex = SectionIndex; AnimatedWorldObjects[a].TrackPosition = TrackPosition; for (int i = 0; i < AnimatedWorldObjects[a].Object.States.Length; i++) { if (AnimatedWorldObjects[a].Object.States[i].Object == null) { AnimatedWorldObjects[a].Object.States[i].Object = new StaticObject(); AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Faces = new World.MeshFace[] { }; AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials = new World.MeshMaterial[] { }; AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Vertices = new World.Vertex[] { }; AnimatedWorldObjects[a].Object.States[i].Object.RendererIndex = -1; } } double r = 0.0; for (int i = 0; i < AnimatedWorldObjects[a].Object.States.Length; i++) { for (int j = 0; j < AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials.Length; j++) { AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.R = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.R * Brightness); AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.G = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.G * Brightness); AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.B = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.B * Brightness); } for (int j = 0; j < AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Vertices.Length; j++) { double x = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.X; double y = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.Y; double z = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.Z; double t = x * x + y * y + z * z; if (t > r) r = t; } } AnimatedWorldObjects[a].Radius = Math.Sqrt(r); AnimatedWorldObjects[a].Visible = false; InitializeAnimatedObject(ref AnimatedWorldObjects[a].Object, 0, false, false); AnimatedWorldObjectsUsed++; return a; }
internal static int CreateAnimatedWorldObject(AnimatedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) { Array.Resize<AnimatedWorldObject>(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1); } World.Transformation FinalTransformation = new World.Transformation(AuxTransformation, BaseTransformation); AnimatedWorldObjects[a] = new AnimatedWorldObject { Position = Position, Direction = FinalTransformation.Z, Up = FinalTransformation.Y, Side = FinalTransformation.X, Object = Prototype.Clone() }; AnimatedWorldObjects[a].Object.ObjectIndex = CreateDynamicObject(); AnimatedWorldObjects[a].SectionIndex = SectionIndex; AnimatedWorldObjects[a].TrackPosition = TrackPosition; //Place track followers if required if (Prototype.TrackFollowerFunction != null) { AnimatedWorldObjects[a].FollowsTrack = true; AnimatedWorldObjects[a].FrontAxleFollower.TrackPosition = TrackPosition + Prototype.FrontAxlePosition; AnimatedWorldObjects[a].RearAxleFollower.TrackPosition = TrackPosition + Prototype.RearAxlePosition; AnimatedWorldObjects[a].FrontAxlePosition = Prototype.FrontAxlePosition; AnimatedWorldObjects[a].RearAxlePosition = Prototype.RearAxlePosition; } for (int i = 0; i < AnimatedWorldObjects[a].Object.States.Length; i++) { if (AnimatedWorldObjects[a].Object.States[i].Object == null) { AnimatedWorldObjects[a].Object.States[i].Object = new StaticObject { Mesh = { Faces = new World.MeshFace[] {}, Materials = new World.MeshMaterial[] {}, Vertices = new World.Vertex[] {} }, RendererIndex = -1 }; } } double r = 0.0; for (int i = 0; i < AnimatedWorldObjects[a].Object.States.Length; i++) { for (int j = 0; j < AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials.Length; j++) { AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.R = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.R * Brightness); AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.G = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.G * Brightness); AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.B = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.B * Brightness); } for (int j = 0; j < AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Vertices.Length; j++) { double x = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.X; double y = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.Y; double z = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.Z; double t = x * x + y * y + z * z; if (t > r) r = t; } } AnimatedWorldObjects[a].Radius = Math.Sqrt(r); AnimatedWorldObjects[a].Visible = false; InitializeAnimatedObject(ref AnimatedWorldObjects[a].Object, 0, false, false); AnimatedWorldObjectsUsed++; return a; }
internal void CreateObject(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) { Array.Resize <WorldObject>(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1); } Transformation FinalTransformation = new Transformation(AuxTransformation, BaseTransformation); //Place track followers if required if (TrackFollowerFunction != null) { var o = this.Clone(); o.ObjectIndex = CreateDynamicObject(); TrackFollowingObject currentObject = new TrackFollowingObject { Position = Position, Direction = FinalTransformation.Z, Up = FinalTransformation.Y, Side = FinalTransformation.X, Object = o, SectionIndex = SectionIndex, TrackPosition = TrackPosition, }; currentObject.FrontAxleFollower.TrackPosition = TrackPosition + FrontAxlePosition; currentObject.RearAxleFollower.TrackPosition = TrackPosition + RearAxlePosition; currentObject.FrontAxlePosition = FrontAxlePosition; currentObject.RearAxlePosition = RearAxlePosition; currentObject.FrontAxleFollower.UpdateWorldCoordinates(false); currentObject.RearAxleFollower.UpdateWorldCoordinates(false); for (int i = 0; i < currentObject.Object.States.Length; i++) { if (currentObject.Object.States[i].Object == null) { currentObject.Object.States[i].Object = new StaticObject(Program.CurrentHost) { RendererIndex = -1 }; } } double r = 0.0; for (int i = 0; i < currentObject.Object.States.Length; i++) { for (int j = 0; j < currentObject.Object.States[i].Object.Mesh.Materials.Length; j++) { currentObject.Object.States[i].Object.Mesh.Materials[j].Color *= Brightness; } for (int j = 0; j < currentObject.Object.States[i].Object.Mesh.Vertices.Length; j++) { double t = States[i].Object.Mesh.Vertices[j].Coordinates.Norm(); if (t > r) { r = t; } } } currentObject.Radius = Math.Sqrt(r); currentObject.Visible = false; currentObject.Object.Initialize(0, false, false); AnimatedWorldObjects[a] = currentObject; } else { var o = this.Clone(); o.ObjectIndex = CreateDynamicObject(); AnimatedWorldObject currentObject = new AnimatedWorldObject { Position = Position, Direction = FinalTransformation.Z, Up = FinalTransformation.Y, Side = FinalTransformation.X, Object = o, SectionIndex = SectionIndex, TrackPosition = TrackPosition, }; for (int i = 0; i < currentObject.Object.States.Length; i++) { if (currentObject.Object.States[i].Object == null) { currentObject.Object.States[i].Object = new StaticObject(Program.CurrentHost) { RendererIndex = -1 }; } } double r = 0.0; for (int i = 0; i < currentObject.Object.States.Length; i++) { for (int j = 0; j < currentObject.Object.States[i].Object.Mesh.Materials.Length; j++) { currentObject.Object.States[i].Object.Mesh.Materials[j].Color *= Brightness; } for (int j = 0; j < currentObject.Object.States[i].Object.Mesh.Vertices.Length; j++) { double t = States[i].Object.Mesh.Vertices[j].Coordinates.Norm(); if (t > r) { r = t; } } } currentObject.Radius = Math.Sqrt(r); currentObject.Visible = false; currentObject.Object.Initialize(0, false, false); AnimatedWorldObjects[a] = currentObject; } AnimatedWorldObjectsUsed++; }
/// <summary>Updates the position and rotation of an animated object which follows a track</summary> /// <param name="Object">The animated object to update</param> internal static void UpdateTrackFollowingObject(ref AnimatedWorldObject Object) { //Get vectors double dx, dy, dz; double ux, uy, uz; double sx, sy, sz; { dx = Object.FrontAxleFollower.WorldPosition.X - Object.RearAxleFollower.WorldPosition.X; dy = Object.FrontAxleFollower.WorldPosition.Y - Object.RearAxleFollower.WorldPosition.Y; dz = Object.FrontAxleFollower.WorldPosition.Z - Object.RearAxleFollower.WorldPosition.Z; double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz); dx *= t; dy *= t; dz *= t; t = 1.0 / Math.Sqrt(dx * dx + dz * dz); double ex = dx * t; double ez = dz * t; sx = ez; sy = 0.0; sz = -ex; World.Cross(dx, dy, dz, sx, sy, sz, out ux, out uy, out uz); } // apply position due to cant/toppling { double a = Object.CurrentRollDueToTopplingAngle + Object.CurrentRollDueToCantAngle; double x = Math.Sign(a) * 0.5 * Game.RouteRailGauge * (1.0 - Math.Cos(a)); double y = Math.Abs(0.5 * Game.RouteRailGauge * Math.Sin(a)); double cx = sx * x + ux * y; double cy = sy * x + uy * y; double cz = sz * x + uz * y; Object.FrontAxleFollower.WorldPosition.X += cx; Object.FrontAxleFollower.WorldPosition.Y += cy; Object.FrontAxleFollower.WorldPosition.Z += cz; Object.RearAxleFollower.WorldPosition.X += cx; Object.RearAxleFollower.WorldPosition.Y += cy; Object.RearAxleFollower.WorldPosition.Z += cz; } // apply rolling { double a = Object.CurrentRollDueToTopplingAngle - Object.CurrentRollDueToCantAngle; double cosa = Math.Cos(a); double sina = Math.Sin(a); World.Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosa, sina); World.Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosa, sina); Object.Up.X = ux; Object.Up.Y = uy; Object.Up.Z = uz; } Object.Direction.X = dx; Object.Direction.Y = dy; Object.Direction.Z = dz; Object.Side.X = sx; Object.Side.Y = sy; Object.Side.Z = sz; }