public void SetModelViewMatrix(Matrix4D modelViewMatrix) { GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(modelViewMatrix.ToArray()); }
public static double Solve(ref Matrix4D m, ref Vector3D v) { double det = m.SubDeterminate(0, 1, 2, 4, 5, 6, 8, 9, 10); if (det != 0) { v.x = (-1d / det) * (m.SubDeterminate(1, 2, 3, 5, 6, 7, 9, 10, 11)); v.y = (1d / det) * (m.SubDeterminate(0, 2, 3, 4, 6, 7, 8, 10, 11)); v.z = (-1d / det) * (m.SubDeterminate(0, 1, 3, 4, 5, 7, 8, 9, 11)); } return det; }
public static TriMesh BulidSphere(string data)//通过文件建立Trimesh { data = "D:\\atet.obj"; TriMesh sphere= FromObjFile(data); Matrix4D m = new Matrix4D(); m[0, 0] = 0.01; m[1, 1] = 0.01; m[2, 2] = 0.01; Vector4D v = new Vector4D(); for (int i = 0; i < sphere.Vertices.Count; i++)//对整个球进行缩放 { v.x = sphere.Vertices[i].Traits.Position.x; v.y = sphere.Vertices[i].Traits.Position.y; v.z = sphere.Vertices[i].Traits.Position.z; v.w = 1; v *= m; sphere.Vertices[i].Traits.Position.x = v.x; sphere.Vertices[i].Traits.Position.y = v.y; sphere.Vertices[i].Traits.Position.z = v.z; } return sphere; }
/// <summary> /// Sets the Matrix4d that represents this instance of <see cref="SlimMath.BoundingFrustum"/>. /// </summary> /// <param name="value">The <see cref="SlimMath.Matrix4d"/> to extract the planes from.</param> public void SetMatrix(ref Matrix4D value) { this.Matrix = value; //Near near.Normal.x = value.M13; near.Normal.y = value.M23; near.Normal.z = value.M33; near.D = value.M43; //Far far.Normal.x = value.M14 - value.M13; far.Normal.y = value.M24 - value.M23; far.Normal.z = value.M34 - value.M33; far.D = value.M44 - value.M43; //Top top.Normal.x = value.M14 - value.M12; top.Normal.y = value.M24 - value.M22; top.Normal.z = value.M34 - value.M32; top.D = value.M44 - value.M42; //Bottom bottom.Normal.x = value.M14 + value.M12; bottom.Normal.y = value.M24 + value.M22; bottom.Normal.z = value.M34 + value.M32; bottom.D = value.M44 + value.M42; //Left left.Normal.x = value.M14 + value.M11; left.Normal.y = value.M24 + value.M21; left.Normal.z = value.M34 + value.M31; left.D = value.M44 + value.M41; //Right right.Normal.x = value.M14 - value.M11; right.Normal.y = value.M24 - value.M21; right.Normal.z = value.M34 - value.M31; right.D = value.M44 - value.M41; }
public void ModelTranslate(double x, double y, double z) { ModelMatrix = ModelMatrix * Matrix4D.Translation(x, y, z); }
private Matrix4D QuatToMatrix4d(Vector4D q) { double n = q.Dot(q); double s = (n > 0.0) ? (2.0 / n) : 0.0f; double xs, ys, zs; double wx, wy, wz; double xx, xy, xz; double yy, yz, zz; xs = q.x * s; ys = q.y * s; zs = q.z * s; wx = q.w * xs; wy = q.w * ys; wz = q.w * zs; xx = q.x * xs; xy = q.x * ys; xz = q.x * zs; yy = q.y * ys; yz = q.y * zs; zz = q.z * zs; Matrix4D m = new Matrix4D(); m[0, 0] = 1.0 - (yy + zz); m[1, 0] = xy - wz; m[2, 0] = xz + wy; m[0, 1] = xy + wz; m[1, 1] = 1.0 - (xx + zz); m[2, 1] = yz - wx; m[0, 2] = xz - wy; m[1, 2] = yz + wx; m[2, 2] = 1.0 - (xx + yy); m[3, 3] = 1.0; return m; }
public static void TransformationVertex(List<TriMesh.Vertex> vertice, Matrix4D m)//对一个Trimesh中的所有点进行旋转 { Vector4D v = new Vector4D(); for (int i = 0; i < vertice.Count; i++) { v.x = vertice[i].Traits.Position.x; v.y = vertice[i].Traits.Position.y; v.z = vertice[i].Traits.Position.z; v.w = 1; v *= m; vertice[i].Traits.Position.x = v.x; vertice[i].Traits.Position.y = v.y; vertice[i].Traits.Position.z = v.z; } }
/// <summary> /// Initializes a new instance of the <see cref="SlimMath.BoundingFrustum"/> class. /// </summary> /// <param name="value">The <see cref="SlimMath.Matrix4d"/> to extract the planes from.</param> public BoundingFrustum(Matrix4D value) { SetMatrix(ref value); }
public void RotateCamera(double x, double y, double z) { ViewMatrix = ViewMatrix * Matrix4D.RotationYawPitchRoll(-y, -x, -z); }
public void LookFromXMinus() { ModelMatrix = Matrix4D.RotationYawPitchRoll(-Math.PI / 2, 0, 0); }
public void ModelShear(double x, double y, double z) { ModelMatrix = ModelMatrix * Matrix4D.Shearing(x, y, z); }
internal static StaticObject ReadObject(string FileName) { currentFolder = System.IO.Path.GetDirectoryName(FileName); currentFile = FileName; rootMatrix = Matrix4D.NoTransformation; #if !DEBUG try { #endif XFileParser parser = new XFileParser(System.IO.File.ReadAllBytes(FileName)); Scene scene = parser.GetImportedData(); StaticObject obj = new StaticObject(Plugin.currentHost); MeshBuilder builder = new MeshBuilder(Plugin.currentHost); if (scene.GlobalMaterials.Count != 0) { for (int i = 0; i < scene.GlobalMeshes.Count; i++) { for (int j = 0; j < scene.GlobalMeshes[i].Materials.Count; j++) { if (scene.GlobalMeshes[i].Materials[j].IsReference) { for (int k = 0; k < scene.GlobalMaterials.Count; k++) { if (scene.GlobalMaterials[k].Name == scene.GlobalMeshes[i].Materials[j].Name) { scene.GlobalMeshes[i].Materials[j] = scene.GlobalMaterials[k]; break; } } } } } } // Global foreach (var mesh in scene.GlobalMeshes) { MeshBuilder(ref obj, ref builder, mesh); } if (scene.RootNode != null) { // Root Node if (scene.RootNode.TrafoMatrix != Matrix4D.Zero) { rootMatrix = new Matrix4D(scene.RootNode.TrafoMatrix); } foreach (var mesh in scene.RootNode.Meshes) { MeshBuilder(ref obj, ref builder, mesh); } // Children Node foreach (var node in scene.RootNode.Children) { ChildrenNode(ref obj, ref builder, node); } } builder.Apply(ref obj); obj.Mesh.CreateNormals(); if (rootMatrix != Matrix4D.NoTransformation) { for (int i = 0; i < obj.Mesh.Vertices.Length; i++) { obj.Mesh.Vertices[i].Coordinates.Transform(rootMatrix); } } return(obj); #if !DEBUG } catch (Exception e) { Plugin.currentHost.AddMessage(MessageType.Error, false, e.Message + " in " + FileName); return(null); } #endif }
public static void TransformationVertex(TriMesh.Vertex vertex, Vector3D vec) { Matrix4D m = ComputeMatrixMove(ref vec); TransformationVertex(vertex, m); }
public static void TransformationScale(TriMesh mesh, double scale) { Matrix4D m = ComputeMatrixScale(scale); TransformationTriMesh(mesh, m); }
public static void TransformationRotation(TriMesh mesh, Vector3D rotation) { Matrix4D m = ComputeMatrixRotation(rotation); TransformationTriMesh(mesh, m); }
public static void TransformationMove(List <TriMesh.Vertex> vertice, Vector3D move) { Matrix4D m = ComputeMatrixMove(ref move); TransformationVertex(vertice, m); }
public static void TransformationMove(TriMesh mesh, Vector3D move) { Matrix4D m = ComputeMatrixMove(ref move); TransformationTriMesh(mesh, m); }
public void ModelScale(double x, double y, double z) { ModelMatrix = ModelMatrix * Matrix4D.Scaling(x, y, z); }
public void ModelMirror(double x, double y, double z) { ModelMatrix = ModelMatrix * Matrix4D.Mirror(x, y, z); }
/// <summary>Creates a static object within the world of the host application, and returns the ObjectManager ID</summary> /// <param name="Prototype">The prototype (un-transformed) static object</param> /// <param name="AuxTransformation">The secondary rail transformation to apply NOTE: Only used for object disposal calcs</param> /// <param name="Rotate">The rotation matrix to apply</param> /// <param name="Translate">The translation matrix to apply</param> /// <param name="AccurateObjectDisposal">Whether accurate object disposal is in use</param> /// <param name="AccurateObjectDisposalZOffset">The offset for accurate Z-disposal</param> /// <param name="StartingDistance">The absolute route based starting distance for the object</param> /// <param name="EndingDistance">The absolute route based ending distance for the object</param> /// <param name="BlockLength">The block length</param> /// <param name="TrackPosition">The absolute route based track position</param> /// <param name="Brightness">The brightness value at this track position</param> /// <returns>The index to the created object, or -1 if this call fails</returns> public virtual int CreateStaticObject(StaticObject Prototype, Transformation AuxTransformation, Matrix4D Rotate, Matrix4D Translate, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness) { return(-1); }
public void Scale(double ratio) { ModelMatrix = Matrix4D.Scaling(ratio) * ModelMatrix; }
public static void LoadingScreenLoop() { currentlyLoading = true; Program.Renderer.PushMatrix(MatrixMode.Projection); Matrix4D.CreateOrthographicOffCenter(0.0f, Program.Renderer.Screen.Width, Program.Renderer.Screen.Height, 0.0f, -1.0f, 1.0f, out Program.Renderer.CurrentProjectionMatrix); Program.Renderer.PushMatrix(MatrixMode.Modelview); Program.Renderer.CurrentViewMatrix = Matrix4D.Identity; while (!Loading.Complete && !Loading.Cancel) { CPreciseTimer.GetElapsedTime(); Program.currentGameWindow.ProcessEvents(); if (Program.currentGameWindow.IsExiting) { Loading.Cancel = true; } double routeProgress = 1.0; for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++) { if (Program.CurrentHost.Plugins[i].Route != null && Program.CurrentHost.Plugins[i].Route.IsLoading) { routeProgress = Program.CurrentHost.Plugins[i].Route.CurrentProgress; } } Program.Renderer.Loading.DrawLoadingScreen(Program.Renderer.Fonts.SmallFont, routeProgress); Program.currentGameWindow.SwapBuffers(); if (Loading.JobAvailable) { while (jobs.Count > 0) { lock (jobLock) { var currentJob = jobs.Dequeue(); var locker = locks.Dequeue(); currentJob(); lock (locker) { Monitor.Pulse(locker); } } } Loading.JobAvailable = false; } double time = CPreciseTimer.GetElapsedTime(); double wait = 1000.0 / 60.0 - time * 1000 - 50; if (wait > 0) { Thread.Sleep((int)(wait)); } } if (!Loading.Cancel) { Program.Renderer.PopMatrix(MatrixMode.Modelview); Program.Renderer.PopMatrix(MatrixMode.Projection); } else { Game.Reset(); currentlyLoading = false; Program.CurrentRouteFile = null; } }
public void LookAtFrom(Vector3D eye,Vector3D target,Vector3D up) { ViewMatrix = Matrix4D.LookAtRH(eye, target, up); }
/// <summary>Draws a 3D cube</summary> /// <param name="VAO"></param> /// <param name="Position">The position in world-space</param> /// <param name="Direction">The direction vector</param> /// <param name="Up">The up vector</param> /// <param name="Side">The side vector</param> /// <param name="Size">A 3D vector describing the size of the cube</param> /// <param name="Camera">The camera position</param> /// <param name="TextureIndex">The texture to apply</param> private void DrawRetained(VertexArrayObject VAO, Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, Vector3 Size, Vector3 Camera, Texture TextureIndex) { renderer.DefaultShader.Activate(); renderer.ResetShader(renderer.DefaultShader); // matrix renderer.DefaultShader.SetCurrentProjectionMatrix(renderer.CurrentProjectionMatrix); renderer.DefaultShader.SetCurrentModelViewMatrix(Matrix4D.Scale(Size) * (Matrix4D) new Transformation(Direction, Up, Side) * Matrix4D.CreateTranslation(Position.X - Camera.X, Position.Y - Camera.Y, -Position.Z + Camera.Z) * renderer.CurrentViewMatrix); // texture if (TextureIndex != null && renderer.currentHost.LoadTexture(TextureIndex, OpenGlTextureWrapMode.ClampClamp)) { GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, TextureIndex.OpenGlTextures[(int)OpenGlTextureWrapMode.ClampClamp].Name); } else { GL.Disable(EnableCap.Texture2D); } // render polygon VAO.Bind(); VAO.Draw(PrimitiveType.Quads); GL.Disable(EnableCap.Texture2D); }
public void SetProjection(int width, int height) { double ratio; if (width > height) { ratio = (width / height) / 2.0; } else { ratio = (height / width) / 2.0; } if (Ortho) { if (width > height) { ProjectionMatrix = Matrix4D.SetOrthoFrustum(-ratio, ratio, -0.5, 0.5, -100, 100); } else { ProjectionMatrix = Matrix4D.SetOrthoFrustum(-0.5, 0.5, -ratio, ratio, -100, 100); } } else { ProjectionMatrix = Matrix4D.SetFrustum(-1, 1, -1, 1, -100, 100.0); } }
public void RenderFaceImmediateMode(ObjectState State, MeshFace Face, bool IsDebugTouchMode = false) { if (State.Prototype.Mesh.Vertices.Length < 1) { return; } VertexTemplate[] vertices = State.Prototype.Mesh.Vertices; MeshMaterial material = State.Prototype.Mesh.Materials[Face.Material]; if (!OptionBackFaceCulling || (Face.Flags & MeshFace.Face2Mask) != 0) { GL.Disable(EnableCap.CullFace); } else if (OptionBackFaceCulling) { if ((Face.Flags & MeshFace.Face2Mask) == 0) { GL.Enable(EnableCap.CullFace); } } Matrix4D modelMatrix = State.ModelMatrix * Camera.TranslationMatrix; // matrix unsafe { GL.MatrixMode(MatrixMode.Projection); GL.PushMatrix(); fixed(double *matrixPointer = &CurrentProjectionMatrix.Row0.X) { GL.LoadMatrix(matrixPointer); } GL.MatrixMode(MatrixMode.Modelview); GL.PushMatrix(); fixed(double *matrixPointer = &CurrentViewMatrix.Row0.X) { GL.LoadMatrix(matrixPointer); } double *matrixPointer2 = &modelMatrix.Row0.X; { GL.MultMatrix(matrixPointer2); } GL.MatrixMode(MatrixMode.Texture); GL.PushMatrix(); fixed(double *matrixPointer = &State.TextureTranslation.Row0.X) { GL.LoadMatrix(matrixPointer); } } if (OptionWireFrame) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } // lighting if (material.NighttimeTexture == null) { if (OptionLighting) { GL.Enable(EnableCap.Lighting); if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new Color4(material.EmissiveColor.R, material.EmissiveColor.G, material.EmissiveColor.B, 255)); } else { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new Color4(0.0f, 0.0f, 0.0f, 1.0f)); } } } // fog if (OptionFog) { GL.Enable(EnableCap.Fog); } PrimitiveType DrawMode; switch (Face.Flags & MeshFace.FaceTypeMask) { case MeshFace.FaceTypeTriangles: DrawMode = PrimitiveType.Triangles; break; case MeshFace.FaceTypeTriangleStrip: DrawMode = PrimitiveType.TriangleStrip; break; case MeshFace.FaceTypeQuads: DrawMode = PrimitiveType.Quads; break; case MeshFace.FaceTypeQuadStrip: DrawMode = PrimitiveType.QuadStrip; break; default: DrawMode = PrimitiveType.Polygon; break; } // daytime polygon { // texture if (material.DaytimeTexture != null) { if (currentHost.LoadTexture(material.DaytimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { GL.Enable(EnableCap.Texture2D); if (LastBoundTexture != material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]; } } } // blend mode float factor; if (material.BlendMode == MeshMaterialBlendMode.Additive) { factor = 1.0f; GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One); GL.Disable(EnableCap.Fog); } else if (material.NighttimeTexture == null) { float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } factor = 1.0f - 0.7f * blend; } else { factor = 1.0f; } float alphaFactor; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, vertices, ref Face, material.GlowAttenuationData); } else { alphaFactor = 1.0f; } GL.Begin(DrawMode); if (OptionWireFrame) { GL.Color4(inv255 * material.Color.R * factor, inv255 * material.Color.G * factor, inv255 * material.Color.B * factor, 1.0f); } else { GL.Color4(inv255 * material.Color.R * factor, inv255 * material.Color.G * factor, inv255 * material.Color.B * factor, inv255 * material.Color.A * alphaFactor); } for (int i = 0; i < Face.Vertices.Length; i++) { GL.Normal3(Face.Vertices[i].Normal.X, Face.Vertices[i].Normal.Y, -Face.Vertices[i].Normal.Z); GL.TexCoord2(vertices[Face.Vertices[i].Index].TextureCoordinates.X, vertices[Face.Vertices[i].Index].TextureCoordinates.Y); if (vertices[Face.Vertices[i].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)vertices[Face.Vertices[i].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X, vertices[Face.Vertices[i].Index].Coordinates.Y, -vertices[Face.Vertices[i].Index].Coordinates.Z); } GL.End(); } // nighttime polygon if (material.NighttimeTexture != null && currentHost.LoadTexture(material.NighttimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { // texture GL.Enable(EnableCap.Texture2D); if (LastBoundTexture != material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]; } GL.Enable(EnableCap.Blend); // alpha test GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Greater, 0.0f); // blend mode float alphaFactor; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, vertices, ref Face, material.GlowAttenuationData); float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } alphaFactor *= blend; } else { alphaFactor = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (alphaFactor > 1.0f) { alphaFactor = 1.0f; } } GL.Begin(DrawMode); if (OptionWireFrame) { GL.Color4(inv255 * material.Color.R, inv255 * material.Color.G, inv255 * material.Color.B, 1.0f); } else { GL.Color4(inv255 * material.Color.R, inv255 * material.Color.G, inv255 * material.Color.B, inv255 * material.Color.A * alphaFactor); } for (int i = 0; i < Face.Vertices.Length; i++) { GL.Normal3(Face.Vertices[i].Normal.X, Face.Vertices[i].Normal.Y, -Face.Vertices[i].Normal.Z); GL.TexCoord2(vertices[Face.Vertices[i].Index].TextureCoordinates.X, vertices[Face.Vertices[i].Index].TextureCoordinates.Y); if (vertices[Face.Vertices[i].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)vertices[Face.Vertices[i].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X, vertices[Face.Vertices[i].Index].Coordinates.Y, -vertices[Face.Vertices[i].Index].Coordinates.Z); } GL.End(); RestoreBlendFunc(); RestoreAlphaFunc(); } GL.Disable(EnableCap.Texture2D); // normals if (OptionNormals) { for (int i = 0; i < Face.Vertices.Length; i++) { GL.Begin(PrimitiveType.Lines); GL.Color4(new Color4(material.Color.R, material.Color.G, material.Color.B, 255)); GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X, vertices[Face.Vertices[i].Index].Coordinates.Y, -vertices[Face.Vertices[i].Index].Coordinates.Z); GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X + Face.Vertices[i].Normal.X, vertices[Face.Vertices[i].Index].Coordinates.Y + +Face.Vertices[i].Normal.Z, -(vertices[Face.Vertices[i].Index].Coordinates.Z + Face.Vertices[i].Normal.Z)); GL.End(); } } // finalize if (OptionWireFrame) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } if (material.BlendMode == MeshMaterialBlendMode.Additive) { RestoreBlendFunc(); } GL.PopMatrix(); GL.MatrixMode(MatrixMode.Modelview); GL.PopMatrix(); GL.MatrixMode(MatrixMode.Projection); GL.PopMatrix(); }
//对一个点或方向向量进行旋转 public static Vector3D TransformationVector3D(Vector3D v, Matrix4D m) { Vector4D v1 = new Vector4D(); v1.x = v.x; v1.y = v.y; v1.z = v.z; v1.w = 1; v1 *= m; v.x = v1.x; v.y = v1.y; v.z = v1.z; return v; }
public int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation AuxTransformation, Matrix4D Rotate, Matrix4D Translate, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness) { if (Prototype == null) { return(-1); } float startingDistance = float.MaxValue; float endingDistance = float.MinValue; if (AccurateObjectDisposal) { foreach (VertexTemplate vertex in Prototype.Mesh.Vertices) { OpenBveApi.Math.Vector3 Coordinates = new Vector3(vertex.Coordinates); Coordinates.Rotate(AuxTransformation); if (Coordinates.Z < startingDistance) { startingDistance = (float)Coordinates.Z; } if (Coordinates.Z > endingDistance) { endingDistance = (float)Coordinates.Z; } } startingDistance += (float)AccurateObjectDisposalZOffset; endingDistance += (float)AccurateObjectDisposalZOffset; } const double minBlockLength = 20.0; if (BlockLength < minBlockLength) { BlockLength *= Math.Ceiling(minBlockLength / BlockLength); } if (AccurateObjectDisposal) { startingDistance += (float)TrackPosition; endingDistance += (float)TrackPosition; double z = BlockLength * Math.Floor(TrackPosition / BlockLength); StartingDistance = Math.Min(z - BlockLength, startingDistance); EndingDistance = Math.Max(z + 2.0 * BlockLength, endingDistance); startingDistance = (float)(BlockLength * Math.Floor(StartingDistance / BlockLength)); endingDistance = (float)(BlockLength * Math.Ceiling(EndingDistance / BlockLength)); } else { startingDistance = (float)StartingDistance; endingDistance = (float)EndingDistance; } StaticObjectStates.Add(new ObjectState { Prototype = Prototype, Translation = Translate, Rotate = Rotate, Brightness = Brightness, StartingDistance = startingDistance, EndingDistance = endingDistance }); foreach (MeshFace face in Prototype.Mesh.Faces) { switch (face.Flags & MeshFace.FaceTypeMask) { case MeshFace.FaceTypeTriangles: InfoTotalTriangles++; break; case MeshFace.FaceTypeTriangleStrip: InfoTotalTriangleStrip++; break; case MeshFace.FaceTypeQuads: InfoTotalQuads++; break; case MeshFace.FaceTypeQuadStrip: InfoTotalQuadStrip++; break; case MeshFace.FaceTypePolygon: InfoTotalPolygon++; break; } } return(StaticObjectStates.Count - 1); }
public static Vector3D TransformOrigin(Matrix4D m) { Vector4D v1 = Vector4D.Zero; v1.w = 1; v1 = v1 * m; Vector3D v = Vector3D.Zero; v.x = v1.x; v.y = v1.y; v.z = v1.z; return v; }
public void RenderFace(Shader Shader, ObjectState State, MeshFace Face, bool IsDebugTouchMode = false) { if (State.Prototype.Mesh.Vertices.Length < 1) { return; } MeshMaterial material = State.Prototype.Mesh.Materials[Face.Material]; VertexArrayObject VAO = (VertexArrayObject)State.Prototype.Mesh.VAO; if (lastVAO != VAO.handle) { VAO.BindForDrawing(Shader.VertexLayout); lastVAO = VAO.handle; } if (!OptionBackFaceCulling || (Face.Flags & MeshFace.Face2Mask) != 0) { GL.Disable(EnableCap.CullFace); } else if (OptionBackFaceCulling) { if ((Face.Flags & MeshFace.Face2Mask) == 0) { GL.Enable(EnableCap.CullFace); } } // matrix Matrix4D modelMatrix = State.ModelMatrix * Camera.TranslationMatrix; Matrix4D modelViewMatrix = modelMatrix * CurrentViewMatrix; Shader.SetCurrentModelViewMatrix(modelViewMatrix); Shader.SetCurrentTextureMatrix(State.TextureTranslation); if (OptionWireFrame || IsDebugTouchMode) { VAO.Draw(PrimitiveType.LineLoop, Face.IboStartIndex, Face.Vertices.Length); return; } // lighting if (material.NighttimeTexture == null || material.NighttimeTexture == material.DaytimeTexture) { if (OptionLighting) { if (material.Color != lastColor) { Shader.SetMaterialAmbient(material.Color); // TODO Shader.SetMaterialDiffuse(material.Color); Shader.SetMaterialSpecular(material.Color); // TODO } if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0) { Shader.SetMaterialEmission(material.EmissiveColor); Shader.SetMaterialEmissive(true); } else { Shader.SetMaterialEmissive(false); } Shader.SetMaterialShininess(1.0f); } else { if (material.Color != lastColor) { Shader.SetMaterialAmbient(material.Color); // TODO } } } else { if (material.Color != lastColor) { Shader.SetMaterialAmbient(material.Color); // TODO } } lastColor = material.Color; PrimitiveType DrawMode; switch (Face.Flags & MeshFace.FaceTypeMask) { case MeshFace.FaceTypeTriangles: DrawMode = PrimitiveType.Triangles; break; case MeshFace.FaceTypeTriangleStrip: DrawMode = PrimitiveType.TriangleStrip; break; case MeshFace.FaceTypeQuads: DrawMode = PrimitiveType.Quads; break; case MeshFace.FaceTypeQuadStrip: DrawMode = PrimitiveType.QuadStrip; break; default: DrawMode = PrimitiveType.Polygon; break; } // daytime polygon { // texture if (material.DaytimeTexture != null && currentHost.LoadTexture(material.DaytimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { Shader.SetIsTexture(true); if (LastBoundTexture != material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]; } } else { Shader.SetIsTexture(false); } // blend mode float factor; if (material.BlendMode == MeshMaterialBlendMode.Additive) { factor = 1.0f; GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One); Shader.SetIsFog(false); } else if (material.NighttimeTexture == null) { float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } factor = 1.0f - 0.7f * blend; } else { factor = 1.0f; } Shader.SetBrightness(factor); float alphaFactor; GlowAttenuationMode mode = GlowAttenuationMode.None; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, State.Prototype.Mesh.Vertices, ref Face, material.GlowAttenuationData, out mode); } else { alphaFactor = 1.0f; } if (material.BlendMode == MeshMaterialBlendMode.Additive) { Shader.SetMaterialAdditive(1 + (int)mode); } else { Shader.SetMaterialAdditive(0); } Shader.SetOpacity(inv255 * material.Color.A * alphaFactor); // render polygon VAO.Draw(DrawMode, Face.IboStartIndex, Face.Vertices.Length); } // nighttime polygon if (material.NighttimeTexture != null && material.NighttimeTexture != material.DaytimeTexture && currentHost.LoadTexture(material.NighttimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { // texture Shader.SetIsTexture(true); if (LastBoundTexture != material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]; } GL.Enable(EnableCap.Blend); // alpha test GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Greater, 0.0f); // blend mode float alphaFactor; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, State.Prototype.Mesh.Vertices, ref Face, material.GlowAttenuationData); float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } alphaFactor *= blend; } else { alphaFactor = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (alphaFactor > 1.0f) { alphaFactor = 1.0f; } } Shader.SetOpacity(alphaFactor); // render polygon VAO.Draw(DrawMode, Face.IboStartIndex, Face.Vertices.Length); RestoreBlendFunc(); RestoreAlphaFunc(); } // normals if (OptionNormals) { Shader.SetIsTexture(false); Shader.SetBrightness(1.0f); Shader.SetOpacity(1.0f); VertexArrayObject NormalsVAO = (VertexArrayObject)State.Prototype.Mesh.NormalsVAO; NormalsVAO.BindForDrawing(Shader.VertexLayout); lastVAO = NormalsVAO.handle; NormalsVAO.Draw(PrimitiveType.Lines, Face.NormalsIboStartIndex, Face.Vertices.Length * 2); } // finalize if (material.BlendMode == MeshMaterialBlendMode.Additive) { RestoreBlendFunc(); Shader.SetIsFog(OptionFog); } }
public static void TransformRotationZ(TriMesh mesh, double sin, double cos)//直接给出参数绕Z轴旋转 { Matrix4D m = ComputeMatrixRotationZ(sin, cos); TransformationTriMesh(mesh, m); }
public void CreateDrawables(DxfModel model, IList <DxfEntity> entities, Matrix4D modelTransform) { this.visualCollection_0.Clear(); WireframeGraphicsFactory2Util.CreateDrawables((IWireframeGraphicsFactory2) new WpfWireframeGraphics3DUsingDrawingVisual.Class380(this), this.graphicsConfig_0, model, entities, modelTransform); }
public void ModelTranslate(Vector3D trans) { ModelMatrix = ModelMatrix * Matrix4D.Translation(trans.x, trans.y, trans.z); }
public static TriMesh BulidSphere()//建立球星Trimesh { TriMesh sphere = new TriMesh(); sphere.Vertices.Add(new VertexTraits(-0.9972, 19.7347, -0.3015)); sphere.Vertices.Add(new VertexTraits(-0.9972, 13.8535, -15.6699)); sphere.Vertices.Add(new VertexTraits(-14.3067, 13.8535, -7.98572)); sphere.Vertices.Add(new VertexTraits(-14.3067, 13.8535, 7.3828)); sphere.Vertices.Add(new VertexTraits(-0.9972, 13.8535, 15.0670)); sphere.Vertices.Add(new VertexTraits(12.3122, 13.8535, 7.3828)); sphere.Vertices.Add(new VertexTraits(12.3122, 13.8535, -7.9857)); sphere.Vertices.Add(new VertexTraits(-0.9972, -3.8925, -15.6699)); sphere.Vertices.Add(new VertexTraits(-14.3067, -3.8925, -7.9857)); sphere.Vertices.Add(new VertexTraits(-14.3067, -3.8925, 7.3828)); sphere.Vertices.Add(new VertexTraits(-0.9972, -3.8925, 15.0670)); sphere.Vertices.Add(new VertexTraits(12.3122, -3.8925, 7.3828)); sphere.Vertices.Add(new VertexTraits(12.3122, -3.8925, -7.9857)); sphere.Vertices.Add(new VertexTraits(-0.9972, -9.7738, -0.3015)); BulidSphereFace(0, 1, 2, sphere); BulidSphereFace(0, 2, 3, sphere); BulidSphereFace(0, 3, 4, sphere); BulidSphereFace(0, 4, 5, sphere); BulidSphereFace(0, 5, 6, sphere); BulidSphereFace(0, 6, 1, sphere); BulidSphereFace(1, 7, 8, sphere); BulidSphereFace(1, 8, 2, sphere); BulidSphereFace(2, 8, 9, sphere); BulidSphereFace(2, 9, 3, sphere); BulidSphereFace(3, 9, 10, sphere); BulidSphereFace(3, 10, 4, sphere); BulidSphereFace(4, 10, 11, sphere); BulidSphereFace(4, 11, 5, sphere); BulidSphereFace(5, 11, 12, sphere); BulidSphereFace(5, 12, 6, sphere); BulidSphereFace(6, 12, 7, sphere); BulidSphereFace(6, 7, 1, sphere); BulidSphereFace(13, 8, 7, sphere); BulidSphereFace(13, 9, 8, sphere); BulidSphereFace(13, 10, 9, sphere); BulidSphereFace(13, 11, 10, sphere); BulidSphereFace(13, 12, 11, sphere); BulidSphereFace(13, 7, 12, sphere); sphere.TrimExcess(); Matrix4D m = new Matrix4D(); m[0, 0] = 0.003; m[1, 1] = 0.003; m[2, 2] = 0.003; Vector4D v = new Vector4D(); for (int i = 0; i < sphere.Vertices.Count; i++)//对整个球进行缩放 { v.x = sphere.Vertices[i].Traits.Position.x; v.y = sphere.Vertices[i].Traits.Position.y; v.z = sphere.Vertices[i].Traits.Position.z; v.w = 1; v *= m; sphere.Vertices[i].Traits.Position.x = v.x; sphere.Vertices[i].Traits.Position.y = v.y; sphere.Vertices[i].Traits.Position.z = v.z; } return(sphere); }
public void ModelScale(Vector3D scale) { ModelMatrix = ModelMatrix * Matrix4D.Scaling(scale.x, scale.y, scale.z); }
internal static void Parse(string fileName, TrainManager.Train Train, ref UnifiedObject[] CarObjects, ref UnifiedObject[] BogieObjects, ref UnifiedObject[] CouplerObjects, ref bool[] interiorVisible) { //The current XML file to load XmlDocument currentXML = new XmlDocument(); //Load the marker's XML file currentXML.Load(fileName); currentPath = System.IO.Path.GetDirectoryName(fileName); if (System.IO.File.Exists(OpenBveApi.Path.CombineFile(currentPath, "train.dat"))) { for (int i = 0; i < Train.Cars.Length; i++) { if (Train.Cars[i].Specs.IsMotorCar) { AccelerationCurves = new BveAccelerationCurve[Train.Cars[i].Specs.AccelerationCurves.Length]; for (int j = 0; j < Train.Cars[i].Specs.AccelerationCurves.Length; j++) { BveAccelerationCurve c = (BveAccelerationCurve)Train.Cars[i].Specs.AccelerationCurves[j]; AccelerationCurves[j] = c.Clone(c.Multiplier); } } } } CarObjectsReversed = new bool[Train.Cars.Length]; BogieObjectsReversed = new bool[Train.Cars.Length * 2]; interiorVisible = new bool[Train.Cars.Length]; if (currentXML.DocumentElement != null) { XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/Train/*[self::Car or self::Coupler]"); if (DocumentNodes == null || DocumentNodes.Count == 0) { Interface.AddMessage(MessageType.Error, false, "No car nodes defined in XML file " + fileName); //If we have no appropriate nodes specified, return false and fallback to loading the legacy Sound.cfg file throw new Exception("Empty train.xml file"); } int carIndex = 0; //Use the index here for easy access to the car count for (int i = 0; i < DocumentNodes.Count; i++) { if (carIndex > Train.Cars.Length) { Interface.AddMessage(MessageType.Warning, false, "WARNING: A total of " + DocumentNodes.Count + " cars were specified in XML file " + fileName + " whilst only " + Train.Cars.Length + " were specified in the train.dat file."); break; } if (DocumentNodes[i].ChildNodes.OfType <XmlElement>().Any()) { if (DocumentNodes[i].Name == "Car") { ParseCarNode(DocumentNodes[i], fileName, carIndex, ref Train, ref CarObjects, ref BogieObjects, ref interiorVisible[carIndex]); } else { if (carIndex - 1 > Train.Cars.Length - 2) { Interface.AddMessage(MessageType.Error, false, "Unexpected extra coupler encountered in XML file " + fileName); continue; } foreach (XmlNode c in DocumentNodes[i].ChildNodes) { switch (c.Name.ToLowerInvariant()) { case "minimum": if (!NumberFormats.TryParseDoubleVb6(c.InnerText, out Train.Cars[carIndex - 1].Coupler.MinimumDistanceBetweenCars)) { Interface.AddMessage(MessageType.Error, false, "MinimumDistanceBetweenCars is invalid for coupler " + carIndex + "in XML file " + fileName); } break; case "maximum": if (!NumberFormats.TryParseDoubleVb6(c.InnerText, out Train.Cars[carIndex - 1].Coupler.MaximumDistanceBetweenCars)) { Interface.AddMessage(MessageType.Error, false, "MaximumDistanceBetweenCars is invalid for coupler " + carIndex + "in XML file " + fileName); } break; case "object": if (string.IsNullOrEmpty(c.InnerText)) { Interface.AddMessage(MessageType.Warning, false, "Invalid object path for Coupler " + (carIndex - 1) + " in XML file " + fileName); break; } string f = OpenBveApi.Path.CombineFile(currentPath, c.InnerText); if (System.IO.File.Exists(f)) { Program.CurrentHost.LoadObject(f, System.Text.Encoding.Default, out CouplerObjects[carIndex - 1]); } break; } } } } else if (!String.IsNullOrEmpty(DocumentNodes[i].InnerText)) { try { string childFile = OpenBveApi.Path.CombineFile(currentPath, DocumentNodes[i].InnerText); XmlDocument childXML = new XmlDocument(); childXML.Load(childFile); XmlNodeList childNodes = childXML.DocumentElement.SelectNodes("/openBVE/Car"); //We need to save and restore the current path to make relative paths within the child file work correctly string savedPath = currentPath; currentPath = System.IO.Path.GetDirectoryName(childFile); ParseCarNode(childNodes[0], fileName, i, ref Train, ref CarObjects, ref BogieObjects, ref interiorVisible[carIndex]); currentPath = savedPath; } catch { Interface.AddMessage(MessageType.Error, false, "Failed to load the child Car XML file specified in " + DocumentNodes[i].InnerText); } } if (i == DocumentNodes.Count && carIndex < Train.Cars.Length) { //If this is the case, the number of motor cars is the primary thing which may get confused.... //Not a lot to be done about this until a full replacement is built for the train.dat file & we can dump it entirely Interface.AddMessage(MessageType.Warning, false, "WARNING: The number of cars specified in the train.xml file does not match that in the train.dat- Some properties may be invalid."); } if (DocumentNodes[i].Name == "Car") { carIndex++; } } if (Train.Cars[Train.DriverCar].CameraRestrictionMode != CameraRestrictionMode.NotSpecified) { Program.Renderer.Camera.CurrentRestriction = Train.Cars[Train.DriverCar].CameraRestrictionMode; Program.Renderer.UpdateViewingDistances(Program.CurrentRoute.CurrentBackground.BackgroundImageDistance); } DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/Train/NotchDescriptions"); if (DocumentNodes != null && DocumentNodes.Count > 0) { //Optional section for (int i = 0; i < DocumentNodes.Count; i++) { if (DocumentNodes[i].ChildNodes.OfType <XmlElement>().Any()) { foreach (XmlNode c in DocumentNodes[i].ChildNodes) { switch (c.Name.ToLowerInvariant()) { case "power": Train.Handles.Power.NotchDescriptions = c.InnerText.Split(new[] { ';' }); for (int j = 0; j < Train.Handles.Power.NotchDescriptions.Length; j++) { Size s = Fonts.NormalFont.MeasureString(Train.Handles.Power.NotchDescriptions[j]); if (s.Width > Train.Handles.Power.MaxWidth) { Train.Handles.Power.MaxWidth = s.Width; } } break; case "brake": Train.Handles.Brake.NotchDescriptions = c.InnerText.Split(new[] { ';' }); for (int j = 0; j < Train.Handles.Brake.NotchDescriptions.Length; j++) { Size s = Fonts.NormalFont.MeasureString(Train.Handles.Brake.NotchDescriptions[j]); if (s.Width > Train.Handles.Brake.MaxWidth) { Train.Handles.Brake.MaxWidth = s.Width; } } break; case "locobrake": if (Train.Handles.LocoBrake == null) { continue; } Train.Handles.LocoBrake.NotchDescriptions = c.InnerText.Split(new[] { ';' }); for (int j = 0; j < Train.Handles.LocoBrake.NotchDescriptions.Length; j++) { Size s = Fonts.NormalFont.MeasureString(Train.Handles.LocoBrake.NotchDescriptions[j]); if (s.Width > Train.Handles.LocoBrake.MaxWidth) { Train.Handles.LocoBrake.MaxWidth = s.Width; } } break; case "reverser": Train.Handles.Reverser.NotchDescriptions = c.InnerText.Split(new[] { ';' }); for (int j = 0; j < Train.Handles.Reverser.NotchDescriptions.Length; j++) { Size s = Fonts.NormalFont.MeasureString(Train.Handles.Reverser.NotchDescriptions[j]); if (s.Width > Train.Handles.Reverser.MaxWidth) { Train.Handles.Reverser.MaxWidth = s.Width; } } break; } } } } } for (int i = 0; i < Train.Cars.Length; i++) { if (CarObjects[i] != null) { if (CarObjectsReversed[i]) { { // reverse axle positions double temp = Train.Cars[i].FrontAxle.Position; Train.Cars[i].FrontAxle.Position = -Train.Cars[i].RearAxle.Position; Train.Cars[i].RearAxle.Position = -temp; } if (CarObjects[i] is StaticObject) { StaticObject obj = (StaticObject)CarObjects[i]; obj.ApplyScale(-1.0, 1.0, -1.0); } else if (CarObjects[i] is AnimatedObjectCollection) { AnimatedObjectCollection obj = (AnimatedObjectCollection)CarObjects[i]; for (int j = 0; j < obj.Objects.Length; j++) { for (int h = 0; h < obj.Objects[j].States.Length; h++) { obj.Objects[j].States[h].Prototype.ApplyScale(-1.0, 1.0, -1.0); Matrix4D t = obj.Objects[j].States[h].Translation; t.Row3.X *= -1.0f; t.Row3.Z *= -1.0f; obj.Objects[j].States[h].Translation = t; } obj.Objects[j].TranslateXDirection.X *= -1.0; obj.Objects[j].TranslateXDirection.Z *= -1.0; obj.Objects[j].TranslateYDirection.X *= -1.0; obj.Objects[j].TranslateYDirection.Z *= -1.0; obj.Objects[j].TranslateZDirection.X *= -1.0; obj.Objects[j].TranslateZDirection.Z *= -1.0; } } else { throw new NotImplementedException(); } } } } //Check for bogie objects and reverse if necessary..... int bogieObjects = 0; for (int i = 0; i < Train.Cars.Length * 2; i++) { bool IsOdd = (i % 2 != 0); int CarIndex = i / 2; if (BogieObjects[i] != null) { bogieObjects++; if (BogieObjectsReversed[i]) { { // reverse axle positions if (IsOdd) { double temp = Train.Cars[CarIndex].FrontBogie.FrontAxle.Position; Train.Cars[CarIndex].FrontBogie.FrontAxle.Position = -Train.Cars[CarIndex].FrontBogie.RearAxle.Position; Train.Cars[CarIndex].FrontBogie.RearAxle.Position = -temp; } else { double temp = Train.Cars[CarIndex].RearBogie.FrontAxle.Position; Train.Cars[CarIndex].RearBogie.FrontAxle.Position = -Train.Cars[CarIndex].RearBogie.RearAxle.Position; Train.Cars[CarIndex].RearBogie.RearAxle.Position = -temp; } } if (BogieObjects[i] is StaticObject) { StaticObject obj = (StaticObject)BogieObjects[i]; obj.ApplyScale(-1.0, 1.0, -1.0); } else if (BogieObjects[i] is AnimatedObjectCollection) { AnimatedObjectCollection obj = (AnimatedObjectCollection)BogieObjects[i]; for (int j = 0; j < obj.Objects.Length; j++) { for (int h = 0; h < obj.Objects[j].States.Length; h++) { obj.Objects[j].States[h].Prototype.ApplyScale(-1.0, 1.0, -1.0); Matrix4D t = obj.Objects[j].States[h].Translation; t.Row3.X *= -1.0f; t.Row3.Z *= -1.0f; obj.Objects[j].States[h].Translation = t; } obj.Objects[j].TranslateXDirection.X *= -1.0; obj.Objects[j].TranslateXDirection.Z *= -1.0; obj.Objects[j].TranslateYDirection.X *= -1.0; obj.Objects[j].TranslateYDirection.Z *= -1.0; obj.Objects[j].TranslateZDirection.X *= -1.0; obj.Objects[j].TranslateZDirection.Z *= -1.0; } } else { throw new NotImplementedException(); } } } } } }
public void ModelMirror(Vector3D mirror) { ModelMatrix = ModelMatrix * Matrix4D.Mirror(mirror.x, mirror.y, mirror.z); }
public override int CreateStaticObject(StaticObject Prototype, Transformation AuxTransformation, Matrix4D Rotate, Matrix4D Translate, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double TrackPosition, double Brightness) { return(Program.Renderer.CreateStaticObject(Prototype, AuxTransformation, Rotate, Translate, Program.CurrentRoute.AccurateObjectDisposal, AccurateObjectDisposalZOffset, StartingDistance, EndingDistance, Program.CurrentRoute.BlockLength, TrackPosition, Brightness)); }
public void ModelShear(Vector3D shear) { ModelMatrix = ModelMatrix * Matrix4D.Shearing(shear.x, shear.y, shear.z); }
public Polygon2D GetProjection2D(Matrix4D projectionTransform) { return(Polygon3D.GetProjection2D((IList <Point3D>) this, projectionTransform)); }
public void LookFromY() { ModelMatrix = Matrix4D.RotationYawPitchRoll(0, Math.PI / 2, 0); }
// render scene internal void RenderScene() { // initialize ResetOpenGlState(); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); CurrentViewMatrix = Matrix4D.LookAt(Vector3.Zero, new Vector3(Camera.AbsoluteDirection.X, Camera.AbsoluteDirection.Y, -Camera.AbsoluteDirection.Z), new Vector3(Camera.AbsoluteUp.X, Camera.AbsoluteUp.Y, -Camera.AbsoluteUp.Z)); OptionFog = false; if (OptionCoordinateSystem) { Cube.Draw(redAxisVAO, Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(100.0, 0.01, 0.01), Camera.AbsolutePosition, null); Cube.Draw(greenAxisVAO, Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(0.01, 100.0, 0.01), Camera.AbsolutePosition, null); Cube.Draw(blueAxisVAO, Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(0.01, 0.01, 100.0), Camera.AbsolutePosition, null); } // opaque face ResetOpenGlState(); foreach (FaceState face in VisibleObjects.OpaqueFaces) { if (Interface.CurrentOptions.IsUseNewRenderer) { DefaultShader.Activate(); ResetShader(DefaultShader); RenderFace(DefaultShader, face); DefaultShader.Deactivate(); } else { RenderFaceImmediateMode(face); } } // alpha face ResetOpenGlState(); VisibleObjects.SortPolygonsInAlphaFaces(); if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance) { SetBlendFunc(); SetAlphaFunc(AlphaFunction.Greater, 0.0f); GL.DepthMask(false); foreach (FaceState face in VisibleObjects.AlphaFaces) { if (Interface.CurrentOptions.IsUseNewRenderer) { DefaultShader.Activate(); ResetShader(DefaultShader); RenderFace(DefaultShader, face); DefaultShader.Deactivate(); } else { RenderFaceImmediateMode(face); } } } else { UnsetBlendFunc(); SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(true); foreach (FaceState face in VisibleObjects.AlphaFaces) { if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Normal && face.Object.Prototype.Mesh.Materials[face.Face.Material].GlowAttenuationData == 0) { if (face.Object.Prototype.Mesh.Materials[face.Face.Material].Color.A == 255) { if (Interface.CurrentOptions.IsUseNewRenderer) { DefaultShader.Activate(); ResetShader(DefaultShader); RenderFace(DefaultShader, face); DefaultShader.Deactivate(); } else { RenderFaceImmediateMode(face); } } } } SetBlendFunc(); SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(false); bool additive = false; foreach (FaceState face in VisibleObjects.AlphaFaces) { if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Additive) { if (!additive) { UnsetAlphaFunc(); additive = true; } if (Interface.CurrentOptions.IsUseNewRenderer) { DefaultShader.Activate(); ResetShader(DefaultShader); RenderFace(DefaultShader, face); DefaultShader.Deactivate(); } else { RenderFaceImmediateMode(face); } } else { if (additive) { SetAlphaFunc(); additive = false; } if (Interface.CurrentOptions.IsUseNewRenderer) { DefaultShader.Activate(); ResetShader(DefaultShader); RenderFace(DefaultShader, face); DefaultShader.Deactivate(); } else { RenderFaceImmediateMode(face); } } } } // render overlays ResetOpenGlState(); OptionLighting = false; UnsetAlphaFunc(); GL.Disable(EnableCap.DepthTest); RenderOverlays(); OptionLighting = true; }
public void LookFromZMinus() { ModelMatrix = Matrix4D.RotationYawPitchRoll(0, 0, -Math.PI / 2); }
private void RenderOverlays() { //Initialize openGL SetBlendFunc(); PushMatrix(MatrixMode.Projection); Matrix4D.CreateOrthographicOffCenter(0.0f, Screen.Width, Screen.Height, 0.0f, -1.0f, 1.0f, out CurrentProjectionMatrix); PushMatrix(MatrixMode.Modelview); CurrentViewMatrix = Matrix4D.Identity; CultureInfo culture = CultureInfo.InvariantCulture; if (OptionInterface) { string[][] keys; if (VisibleObjects.Objects.Count == 0 && ObjectManager.AnimatedWorldObjectsUsed == 0) { keys = new[] { new[] { "F7" }, new[] { "F8" }, new[] { "F10" } }; Keys.Render(4, 4, 20, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, "Open one or more objects", new Point(32, 4), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the options window", new Point(32, 24), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the train settings window", new Point(32, 44), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"v{System.Windows.Forms.Application.ProductVersion}", new Point(Screen.Width - 8, Screen.Height - 20), TextAlignment.TopLeft, TextColor); } else { OpenGlString.Draw(Fonts.SmallFont, $"Position: {Camera.AbsolutePosition.X.ToString("0.00", culture)}, {Camera.AbsolutePosition.Y.ToString("0.00", culture)}, {Camera.AbsolutePosition.Z.ToString("0.00", culture)}", new Point((int)(0.5 * Screen.Width - 88), 4), TextAlignment.TopLeft, TextColor); keys = new[] { new[] { "F5" }, new[] { "F7" }, new[] { "del" }, new[] { "F8" }, new[] { "F10" } }; Keys.Render(4, 4, 24, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, "Reload the currently open objects", new Point(32, 4), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Open additional objects", new Point(32, 24), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Clear currently open objects", new Point(32, 44), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the options window", new Point(32, 64), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the train settings window", new Point(32, 84), TextAlignment.TopLeft, TextColor); keys = new[] { new[] { "F" }, new[] { "N" }, new[] { "L" }, new[] { "G" }, new[] { "B" }, new[] { "I" } }; Keys.Render(Screen.Width - 20, 4, 16, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, $"WireFrame: {(OptionWireFrame ? "on" : "off")}", new Point(Screen.Width - 28, 4), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Normals: {(OptionNormals ? "on" : "off")}", new Point(Screen.Width - 28, 24), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Lighting: {(Program.LightingTarget == 0 ? "night" : "day")}", new Point(Screen.Width - 28, 44), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Grid: {(OptionCoordinateSystem ? "on" : "off")}", new Point(Screen.Width - 28, 64), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Background: {GetBackgroundColorName()}", new Point(Screen.Width - 28, 84), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Hide interface", new Point(Screen.Width - 28, 104), TextAlignment.TopRight, TextColor); keys = new[] { new[] { null, "W", null }, new[] { "A", "S", "D" } }; Keys.Render(4, Screen.Height - 40, 16, Fonts.SmallFont, keys); keys = new[] { new[] { null, "↑", null }, new[] { "←", "↓", "→" } }; Keys.Render((int)(0.5 * Screen.Width - 28), Screen.Height - 40, 16, Fonts.SmallFont, keys); keys = new[] { new[] { null, "8", "9" }, new[] { "4", "5", "6" }, new[] { null, "2", "3" } }; Keys.Render(Screen.Width - 60, Screen.Height - 60, 16, Fonts.SmallFont, keys); if (Interface.MessageCount == 1) { Keys.Render(4, 112, 20, Fonts.SmallFont, new[] { new[] { "F9" } }); if (Interface.LogMessages[0].Type != MessageType.Information) { OpenGlString.Draw(Fonts.SmallFont, "Display the 1 error message recently generated.", new Point(32, 112), TextAlignment.TopLeft, new Color128(1.0f, 0.5f, 0.5f)); } else { //If all of our messages are information, then print the message text in grey OpenGlString.Draw(Fonts.SmallFont, "Display the 1 message recently generated.", new Point(32, 112), TextAlignment.TopLeft, TextColor); } } else if (Interface.MessageCount > 1) { Keys.Render(4, 112, 20, Fonts.SmallFont, new[] { new[] { "F9" } }); bool error = Interface.LogMessages.Any(x => x.Type != MessageType.Information); if (error) { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.MessageCount.ToString(culture)} error messages recently generated.", new Point(32, 112), TextAlignment.TopLeft, new Color128(1.0f, 0.5f, 0.5f)); } else { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.MessageCount.ToString(culture)} messages recently generated.", new Point(32, 112), TextAlignment.TopLeft, TextColor); } } } } // finalize PopMatrix(MatrixMode.Projection); PopMatrix(MatrixMode.Modelview); }
public void TranslateCamera(double x, double y, double z) { ViewMatrix = ViewMatrix * Matrix4D.Translation(-x, -y, -z); }
/// <summary> Updates the position and state of the animated object</summary> /// <param name="IsPartOfTrain">Whether this object forms part of a train</param> /// <param name="Train">The train, or a null reference otherwise</param> /// <param name="CarIndex">If this object forms part of a train, the car index it refers to</param> /// <param name="SectionIndex">If this object has been placed via Track.Sig, the index of the section it is attached to</param> /// <param name="TrackPosition"></param> /// <param name="Position"></param> /// <param name="Direction"></param> /// <param name="Up"></param> /// <param name="Side"></param> /// <param name="UpdateFunctions">Whether the functions associated with this object should be re-evaluated</param> /// <param name="Show"></param> /// <param name="TimeElapsed">The time elapsed since this object was last updated</param> /// <param name="EnableDamping">Whether damping is to be applied for this call</param> /// <param name="IsTouch">Whether Animated Object belonging to TouchElement class.</param> /// <param name="Camera"></param> public void Update(bool IsPartOfTrain, AbstractTrain Train, int CarIndex, int SectionIndex, double TrackPosition, Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, bool UpdateFunctions, bool Show, double TimeElapsed, bool EnableDamping, bool IsTouch = false, dynamic Camera = null) { int s = CurrentState; // state change if (StateFunction != null & UpdateFunctions) { double sd = StateFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); int si = (int)System.Math.Round(sd); int sn = States.Length; if (si < 0 | si >= sn) { si = -1; } if (s != si) { ObjectType type = ObjectType.Dynamic; if (Camera != null) { type = ObjectType.Overlay; } Initialize(si, type, Show); s = si; } } if (s == -1) { return; } // translation if (TranslateXFunction != null) { double x; if (UpdateFunctions) { x = TranslateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { x = TranslateXFunction.LastResult; } Vector3 translationVector = new Vector3(TranslateXDirection); //Must clone translationVector.Rotate(Direction, Up, Side); translationVector *= x; Position += translationVector; } else if (TranslateXScriptFile != null) { //Translate X Script if (TranslateXAnimationScript == null) { //Load the script if required try { CSScript.GlobalSettings.TargetFramework = "v4.0"; TranslateXAnimationScript = CSScript.LoadCode(File.ReadAllText(TranslateXScriptFile)) .CreateObject("OpenBVEScript") .AlignToInterface <AnimationScript>(true); } catch { currentHost.AddMessage(MessageType.Error, false, "An error occcured whilst parsing script " + TranslateXScriptFile); TranslateXScriptFile = null; return; } } double x = TranslateXAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed); Vector3 translationVector = new Vector3(TranslateXDirection); //Must clone translationVector.Rotate(Direction, Up, Side); translationVector *= x; Position += translationVector; } if (TranslateYFunction != null) { double y; if (UpdateFunctions) { y = TranslateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { y = TranslateYFunction.LastResult; } Vector3 translationVector = new Vector3(TranslateYDirection); //Must clone translationVector.Rotate(Direction, Up, Side); translationVector *= y; Position += translationVector; } else if (TranslateYScriptFile != null) { //Translate X Script if (TranslateYAnimationScript == null) { //Load the script if required try { CSScript.GlobalSettings.TargetFramework = "v4.0"; TranslateYAnimationScript = CSScript.LoadCode(File.ReadAllText(TranslateYScriptFile)) .CreateObject("OpenBVEScript") .AlignToInterface <AnimationScript>(true); } catch { currentHost.AddMessage(MessageType.Error, false, "An error occcured whilst parsing script " + TranslateYScriptFile); TranslateYScriptFile = null; return; } } double y = TranslateYAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed); Vector3 translationVector = new Vector3(TranslateYDirection); //Must clone translationVector.Rotate(Direction, Up, Side); translationVector *= y; Position += translationVector; } if (TranslateZFunction != null) { double z; if (UpdateFunctions) { z = TranslateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { z = TranslateZFunction.LastResult; } Vector3 translationVector = new Vector3(TranslateZDirection); //Must clone translationVector.Rotate(Direction, Up, Side); translationVector *= z; Position += translationVector; } else if (TranslateZScriptFile != null) { //Translate X Script if (TranslateZAnimationScript == null) { //Load the script if required try { CSScript.GlobalSettings.TargetFramework = "v4.0"; TranslateZAnimationScript = CSScript.LoadCode(File.ReadAllText(TranslateZScriptFile)) .CreateObject("OpenBVEScript") .AlignToInterface <AnimationScript>(true); } catch { currentHost.AddMessage(MessageType.Error, false, "An error occcured whilst parsing script " + TranslateZScriptFile); TranslateZScriptFile = null; return; } } double z = TranslateZAnimationScript.ExecuteScript(Train, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed); Vector3 translationVector = new Vector3(TranslateZDirection); //Must clone translationVector.Rotate(Direction, Up, Side); translationVector *= z; Position += translationVector; } // rotation bool rotateX = RotateXFunction != null; bool rotateY = RotateYFunction != null; bool rotateZ = RotateZFunction != null; double radianX; if (rotateX) { double a; if (UpdateFunctions) { a = RotateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { a = RotateXFunction.LastResult; } if (RotateXDamping != null) { RotateXDamping.Update(TimeElapsed, ref a, EnableDamping); } radianX = a; } else { radianX = 0.0; } double radianY; if (rotateY) { double a; if (UpdateFunctions) { a = RotateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { a = RotateYFunction.LastResult; } if (RotateYDamping != null) { RotateYDamping.Update(TimeElapsed, ref a, EnableDamping); } radianY = a; } else { radianY = 0.0; } double radianZ; if (rotateZ) { double a; if (UpdateFunctions) { a = RotateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { a = RotateZFunction.LastResult; } if (RotateZDamping != null) { RotateZDamping.Update(TimeElapsed, ref a, EnableDamping); } radianZ = a; } else { radianZ = 0.0; } // texture shift bool shiftx = TextureShiftXFunction != null; bool shifty = TextureShiftYFunction != null; internalObject.TextureTranslation = Matrix4D.Identity; if (shiftx | shifty) { if (shiftx) { double x; if (UpdateFunctions) { x = TextureShiftXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { x = TextureShiftXFunction.LastResult; } x -= System.Math.Floor(x); internalObject.TextureTranslation *= Matrix4D.CreateTranslation(x * TextureShiftXDirection.X, x * TextureShiftXDirection.Y, 1.0); } if (shifty) { double y; if (UpdateFunctions) { y = TextureShiftYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { y = TextureShiftYFunction.LastResult; } y -= System.Math.Floor(y); internalObject.TextureTranslation *= Matrix4D.CreateTranslation(y * TextureShiftYDirection.X, y * TextureShiftYDirection.Y, 1.0); } } // led bool led = LEDFunction != null; double ledangle; if (led) { if (UpdateFunctions) { ledangle = LEDFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, CurrentState); } else { ledangle = LEDFunction.LastResult; } } else { ledangle = 0.0; } // null object if (States[s].Prototype == null) { return; } // led if (led) { /* * Edges: Vertices: * 0 - bottom 0 - bottom-left * 1 - left 1 - top-left * 2 - top 2 - top-right * 3 - right 3 - bottom-right * 4 - center * */ int v = 1; if (LEDClockwiseWinding) { /* winding is clockwise*/ if (ledangle < LEDInitialAngle) { ledangle = LEDInitialAngle; } if (ledangle < LEDLastAngle) { double currentEdgeFloat = System.Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449)); int currentEdge = ((int)currentEdgeFloat % 4 + 4) % 4; double lastEdgeFloat = System.Math.Floor(0.636619772367582 * (LEDLastAngle + 0.785398163397449)); int lastEdge = ((int)lastEdgeFloat % 4 + 4) % 4; if (lastEdge < currentEdge | lastEdge == currentEdge & System.Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0) { lastEdge += 4; } if (currentEdge == lastEdge) { /* current angle to last angle */ { double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X; double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y; double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z; States[s].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(cx, cy, cz); v++; } { double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X; double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y; double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z; States[s].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(lx, ly, lz); v++; } } else { { /* current angle to square vertex */ double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X; double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y; double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z; States[s].Prototype.Mesh.Vertices[v + 0].Coordinates = new Vector3(cx, cy, cz); States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[currentEdge]; v += 2; } for (int j = currentEdge + 1; j < lastEdge; j++) { /* square-vertex to square-vertex */ States[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4]; States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[j % 4]; v += 2; } { /* square vertex to last angle */ double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge % 4].X; double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge % 4].Y; double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge % 4].Z; States[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(lastEdge + 3) % 4]; States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = new Vector3(lx, ly, lz); v += 2; } } } } else { /* winding is counter-clockwise*/ if (ledangle > LEDInitialAngle) { ledangle = LEDInitialAngle; } if (ledangle > LEDLastAngle) { double currentEdgeFloat = System.Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449)); int currentEdge = ((int)currentEdgeFloat % 4 + 4) % 4; double lastEdgeFloat = System.Math.Floor(0.636619772367582 * (LEDLastAngle + 0.785398163397449)); int lastEdge = ((int)lastEdgeFloat % 4 + 4) % 4; if (currentEdge < lastEdge | lastEdge == currentEdge & System.Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0) { currentEdge += 4; } if (currentEdge == lastEdge) { /* current angle to last angle */ { double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X; double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y; double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z; States[s].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(lx, ly, lz); v++; } { double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = t - System.Math.Floor(t); t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge].X; double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge].Y; double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge].Z; States[s].Prototype.Mesh.Vertices[v].Coordinates = new Vector3(cx, cy, cz); v++; } } else { { /* current angle to square vertex */ double t = 0.5 + 0.636619772367582 * ledangle - currentEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double cx = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].X + t * LEDVectors[currentEdge % 4].X; double cy = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Y + t * LEDVectors[currentEdge % 4].Y; double cz = (1.0 - t) * LEDVectors[(currentEdge + 3) % 4].Z + t * LEDVectors[currentEdge % 4].Z; States[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(currentEdge + 3) % 4]; States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = new Vector3(cx, cy, cz); v += 2; } for (int j = currentEdge - 1; j > lastEdge; j--) { /* square-vertex to square-vertex */ States[s].Prototype.Mesh.Vertices[v + 0].Coordinates = LEDVectors[(j + 3) % 4]; States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[j % 4]; v += 2; } { /* square vertex to last angle */ double t = 0.5 + 0.636619772367582 * LEDLastAngle - lastEdgeFloat; if (t < 0.0) { t = 0.0; } else if (t > 1.0) { t = 1.0; } t = 0.5 * (1.0 - System.Math.Tan(0.25 * (System.Math.PI - 2.0 * System.Math.PI * t))); double lx = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].X + t * LEDVectors[lastEdge].X; double ly = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Y + t * LEDVectors[lastEdge].Y; double lz = (1.0 - t) * LEDVectors[(lastEdge + 3) % 4].Z + t * LEDVectors[lastEdge].Z; States[s].Prototype.Mesh.Vertices[v + 0].Coordinates = new Vector3(lx, ly, lz); States[s].Prototype.Mesh.Vertices[v + 1].Coordinates = LEDVectors[lastEdge % 4]; v += 2; } } } } for (int j = v; v < 11; v++) { States[s].Prototype.Mesh.Vertices[j].Coordinates = LEDVectors[4]; } } // update prototype internalObject.Prototype = States[s].Prototype; // update VAO for led if required UpdateVAO = led; // update state // rotate internalObject.Rotate = Matrix4D.Identity; if (rotateX) { internalObject.Rotate *= Matrix4D.CreateFromAxisAngle(new Vector3(RotateXDirection.X, RotateXDirection.Y, -RotateXDirection.Z), 2.0 * System.Math.PI - radianX); } if (rotateY) { internalObject.Rotate *= Matrix4D.CreateFromAxisAngle(new Vector3(RotateYDirection.X, RotateYDirection.Y, -RotateYDirection.Z), 2.0 * System.Math.PI - radianY); } if (rotateZ) { internalObject.Rotate *= Matrix4D.CreateFromAxisAngle(new Vector3(RotateZDirection.X, RotateZDirection.Y, -RotateZDirection.Z), 2.0 * System.Math.PI - radianZ); } if (Camera != null && Camera.CurrentRestriction != CameraRestrictionMode.NotAvailable && Camera.CurrentRestriction != CameraRestrictionMode.Restricted3D) { internalObject.Rotate *= States[s].Translation * Matrix4D.CreateTranslation(-Position.X, -Position.Y, Position.Z); internalObject.Rotate *= (Matrix4D) new Transformation((Vector3)Camera.AbsoluteDirection, (Vector3)Camera.AbsoluteUp, (Vector3)Camera.AbsoluteSide); // translate double dx = -System.Math.Tan(Camera.Alignment.Yaw) - Camera.Alignment.Position.X; double dy = -System.Math.Tan(Camera.Alignment.Pitch) - Camera.Alignment.Position.Y; double dz = -Camera.Alignment.Position.Z; Vector3 add = Camera.AbsolutePosition + dx * Camera.AbsoluteSide + dy * Camera.AbsoluteUp + dz * Camera.AbsoluteDirection; internalObject.Translation = Matrix4D.CreateTranslation(add.X, add.Y, -add.Z); } else { internalObject.Rotate *= States[s].Translation; internalObject.Rotate *= (Matrix4D) new Transformation(Direction, Up, Side); // translate internalObject.Translation = Matrix4D.CreateTranslation(Position.X, Position.Y, -Position.Z); } // visibility changed // TouchElement is handled by another function. if (!IsTouch) { if (Show) { if (Camera != null) { currentHost.ShowObject(internalObject, ObjectType.Overlay); } else { currentHost.ShowObject(internalObject, ObjectType.Dynamic); } } else { currentHost.HideObject(internalObject); } } }
public void SetCamearPosition(double x, double y, double z) { ViewMatrix = Matrix4D.LookAtRH(new Vector3D(x,y,z), Vector3D.Zero, Vector3D.UnitY); }
public override int CreateStaticObject(StaticObject Prototype, Transformation LocalTransformation, Matrix4D Rotate, Matrix4D Translate, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double TrackPosition, double Brightness) { return(Program.Renderer.CreateStaticObject(Prototype, LocalTransformation, Rotate, Translate, ObjectDisposalMode.Accurate, AccurateObjectDisposalZOffset, StartingDistance, EndingDistance, 25.0, TrackPosition, Brightness)); }
public void SetFrustumOrtho(double left, double right, double bottom, double top, double near, double far) { ProjectionMatrix = Matrix4D.SetOrthoFrustum(left, right, bottom, top, near, far); }
public void CreateMText(DxfMText text, DrawContext.Wireframe drawContext) { if (text.Text == null || text.Text.Trim() == string.Empty) { return; } Bounds2D collectBounds = new Bounds2D(); IList <Class908> chunks = Class666.smethod_4(text, text.Color.ToColor(), drawContext.GetLineWeight((DxfEntity)text), drawContext.GetTransformer().Matrix, collectBounds); BackgroundFillFlags backgroundFillFlags = text.BackgroundFillFlags; BackgroundFillInfo backgroundFillInfo = text.BackgroundFillInfo; if (backgroundFillFlags == BackgroundFillFlags.UseBackgroundFillColor && backgroundFillInfo != null) { System.Drawing.Color color = (System.Drawing.Color)DxfEntity.GetColor(this.graphicsConfig_0.IndexedColors, backgroundFillInfo.Color, drawContext.ByBlockColor, drawContext.ByBlockDxfColor, text.GetLayer((DrawContext)drawContext)); double num1 = text.Height * (backgroundFillInfo.BorderOffsetFactor - 1.0); double x1 = collectBounds.Center.X; double y1 = collectBounds.Center.Y; double width = text.Width; double y2 = collectBounds.Delta.Y; double num2; double num3; switch (text.AttachmentPoint) { case AttachmentPoint.TopLeft: num2 = collectBounds.Corner1.X + 0.5 * width; num3 = collectBounds.Corner2.Y - 0.5 * y2; break; case AttachmentPoint.TopCenter: num2 = collectBounds.Center.X; num3 = collectBounds.Corner2.Y - 0.5 * y2; break; case AttachmentPoint.TopRight: num2 = collectBounds.Corner2.X - 0.5 * width; num3 = collectBounds.Corner2.Y - 0.5 * y2; break; case AttachmentPoint.MiddleLeft: num2 = collectBounds.Corner1.X + 0.5 * width; num3 = collectBounds.Center.Y; break; case AttachmentPoint.MiddleCenter: num2 = collectBounds.Center.X; num3 = collectBounds.Center.Y; break; case AttachmentPoint.MiddleRight: num2 = collectBounds.Corner2.X - 0.5 * width; num3 = collectBounds.Center.Y; break; case AttachmentPoint.BottomLeft: num2 = collectBounds.Corner1.X + 0.5 * width; num3 = collectBounds.Corner1.Y + 0.5 * y2; break; case AttachmentPoint.BottomCenter: num2 = collectBounds.Center.X; num3 = collectBounds.Corner1.Y + 0.5 * y2; break; case AttachmentPoint.BottomRight: num2 = collectBounds.Corner2.X - 0.5 * width; num3 = collectBounds.Corner1.Y + 0.5 * y2; break; default: num2 = collectBounds.Center.X; num3 = collectBounds.Center.Y; break; } short lineWeight = drawContext.GetLineWeight((DxfEntity)text); Matrix4D matrix4D = drawContext.GetTransformer().Matrix *text.Transform; WW.Math.Point2D point = new WW.Math.Point2D(num2 - 0.5 * width - num1, num3 - 0.5 * y2 - num1); double x2 = width + 2.0 * num1; double y3 = y2 + 2.0 * num1; this.method_4(false, (Interface12) new Class341((ArgbColor)color, (Interface23) new Class535(true, new Vector4D[4] { matrix4D.TransformTo4D(point), matrix4D.TransformTo4D(point + new Vector2D(x2, 0.0)), matrix4D.TransformTo4D(point + new Vector2D(x2, y3)), matrix4D.TransformTo4D(point + new Vector2D(0.0, y3)) }), true, lineWeight)); } this.method_3(chunks, (DxfEntity)text, drawContext); }
public void AddDrawables(DxfModel model, Matrix4D modelTransform) { GDIGraphics3D.smethod_0(); WireframeGraphicsFactoryUtil.CreateDrawables((IWireframeGraphicsFactory) new GDIGraphics3D.Class942(this), this.graphicsConfig_0, model, modelTransform); }
public void Draw(Graphics graphics, Rectangle drawingBounds, Matrix4D transform) { this.Draw(graphics, drawingBounds, transform, (System.Drawing.Color) this.graphicsConfig_0.BackColor); }
public static void TransformationTriMesh(TriMesh mesh, Matrix4D m)//对一个Trimesh中的所有点进行旋转 { Vector4D v = new Vector4D(); for (int i = 0; i < mesh.Vertices.Count; i++)//对每个点进行变换 { v.x = mesh.Vertices[i].Traits.Position.x; v.y = mesh.Vertices[i].Traits.Position.y; v.z = mesh.Vertices[i].Traits.Position.z; v.w = 1; v *= m; mesh.Vertices[i].Traits.Position.x = v.x; mesh.Vertices[i].Traits.Position.y = v.y; mesh.Vertices[i].Traits.Position.z = v.z; } }
public GDIGraphics3D(GraphicsConfig config, Matrix4D to2DTransform) { this.method_1(config, to2DTransform); }
public static void TransformationVertex( TriMesh.Vertex vertex, Matrix4D m) { Vector4D v = new Vector4D(); v.x = vertex.Traits.Position.x; v.y = vertex.Traits.Position.y; v.z = vertex.Traits.Position.z; v.w = 1; v *= m; vertex.Traits.Position.x = v.x; vertex.Traits.Position.y = v.y; vertex.Traits.Position.z = v.z; }
public void Draw(System.Drawing.Graphics graphics) { var rnd = new Random(15); var whitePen = new Pen(Color.White, 1); var screenMid = new Vertex(800 / 2, 600 / 2, 0); var projectMat = Camera.GetProjectionMatrix(); var transLationMat = Camera.GetTranslationMatrix(); var bufferedImage = new BufferedImage(800, 600); var g = bufferedImage.GetGraphics(); bufferedImage.Bitmap.SetPixel((int)screenMid.X, (int)screenMid.Y, Color.Cyan); g.DrawRectangle(new Pen(Color.Cyan), 0, 0, 800 - 1, 600 - 1); foreach (var mesh in Meshes) { foreach (var face in mesh.Faces) { // Static flip var rotTest = Matrix4D.GetXRot((Math.PI * 160) / 180); YROT += .0001; var rotTest2 = Matrix4D.GetYRot((Math.PI * (YROT)) / 180); var scaleTest = Matrix4D.GetScale(600 / 2, 600 / 2, 1); var temp = face.Vertex1; var translatedV1 = Matrix1D.From(mesh.Vertices[face.Vertex1]); var translatedV2 = Matrix1D.From(mesh.Vertices[face.Vertex2]); var translatedV3 = Matrix1D.From(mesh.Vertices[face.Vertex3]); translatedV1 = translatedV1.Multiply(rotTest2); translatedV2 = translatedV2.Multiply(rotTest2); translatedV3 = translatedV3.Multiply(rotTest2); translatedV1 = translatedV1.Multiply(rotTest); translatedV2 = translatedV2.Multiply(rotTest); translatedV3 = translatedV3.Multiply(rotTest); /* * Console.WriteLine(translatedV1); * Console.WriteLine(rotTest); */ translatedV1 = translatedV1.Multiply(scaleTest); translatedV2 = translatedV2.Multiply(scaleTest); translatedV3 = translatedV3.Multiply(scaleTest); translatedV1 = translatedV1.Multiply(transLationMat); translatedV2 = translatedV2.Multiply(transLationMat); translatedV3 = translatedV3.Multiply(transLationMat); translatedV1 = translatedV1.Multiply(projectMat); translatedV2 = translatedV2.Multiply(projectMat); translatedV3 = translatedV3.Multiply(projectMat); var resultV1 = Vertex.From(translatedV1); var resultV2 = Vertex.From(translatedV2); var resultV3 = Vertex.From(translatedV3); if (translatedV1.Z != 0) { resultV1.X /= translatedV1.Z; resultV1.Y /= translatedV1.Z; } if (translatedV2.Z != 0) { resultV2.X /= translatedV2.Z; resultV2.Y /= translatedV2.Z; } if (translatedV3.Z != 0) { resultV3.X /= translatedV3.Z; resultV3.Y /= translatedV3.Z; } resultV1.X += screenMid.X; resultV1.Y += screenMid.Y; resultV2.X += screenMid.X; resultV2.Y += screenMid.Y; resultV3.X += screenMid.X; resultV3.Y += screenMid.Y; if (resultV1.Z <= 0.1 || resultV2.Z <= 0.1 || resultV3.Z <= 0.1) { continue; } /* * g.DrawString($"{Math.Round(test1.X, 3)},{Math.Round(test1.Y, 3)},{Math.Round(test1.Z, 3)}", new Font(FontFamily.GenericSansSerif, 14), Brushes.Cyan, (float)resultV1.X, (float)resultV1.Y); * g.DrawString($"{Math.Round(test2.X, 3)},{Math.Round(test2.Y, 3)},{Math.Round(test2.Z, 3)}", new Font(FontFamily.GenericSansSerif, 14), Brushes.Cyan, (float)resultV2.X, (float)resultV2.Y); * g.DrawString($"{Math.Round(test3.X, 3)},{Math.Round(test3.Y, 3)},{Math.Round(test3.Z, 3)}", new Font(FontFamily.GenericSansSerif, 14), Brushes.Cyan, (float)resultV3.X, (float)resultV3.Y); */ if (ColorfullPolygonDisplayEnabled) { var color = Color.FromArgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255), 255); g.FillPolygon( new SolidBrush(color), new PointF[] { new PointF((float)resultV1.X, (float)resultV1.Y), new PointF((float)resultV2.X, (float)resultV2.Y), new PointF((float)resultV3.X, (float)resultV3.Y) }); } var v = resultV2.Clone().Subtract(resultV1); var w = resultV3.Clone().Subtract(resultV1); var n = new Vertex() { X = (v.Y * w.Z) - (v.Z * w.Y), Y = (v.Z * w.X) - (v.X * w.Z), Z = (v.X * w.Y) - (v.Y * w.X) }; if (PointDisplayEnabled) { SetPixel(bufferedImage.Bitmap, (int)resultV1.X, (int)resultV1.Y); SetPixel(bufferedImage.Bitmap, (int)resultV1.X, (int)resultV1.Y); SetPixel(bufferedImage.Bitmap, (int)resultV1.X, (int)resultV1.Y); } if (WireframeDisplayEnabled) { g.DrawLine(whitePen, (float)resultV1.X, (float)resultV1.Y, (float)resultV2.X, (float)resultV2.Y); g.DrawLine(whitePen, (float)resultV2.X, (float)resultV2.Y, (float)resultV3.X, (float)resultV3.Y); g.DrawLine(whitePen, (float)resultV3.X, (float)resultV3.Y, (float)resultV1.X, (float)resultV1.Y); } /* * g.DrawPolygon( * new Pen(Color.FromArgb(rnd.Next(0,255),rnd.Next(0,255),rnd.Next(0,255), 255)), new Point[]{ * new Point((int)translatedV1.X, (int)translatedV1.Y), * new Point((int)translatedV2.X, (int)translatedV2.Y), * new Point((int)translatedV3.X, (int)translatedV3.Y) * }); */ } } Console.WriteLine($"{Camera.Pos.X},{Camera.Pos.Y},{Camera.Pos.Z}"); g.Dispose(); graphics.DrawImage(bufferedImage.Bitmap, 0, 0); }
private double GetError(Matrix4D Q, Vector3D v) { double x = v.x; double y = v.y; double z = v.z; return Q[0] * x * x + 2 * Q[1] * x * y + 2 * Q[2] * x * z + 2 * Q[3] * x + Q[5] * y * y + 2 * Q[6] * y * z + 2 * Q[7] * y + Q[10] * z * z + 2 * Q[11] * z + Q[15]; }
internal static void ParseExtensionsConfig(string filePath, Encoding encoding, out UnifiedObject[] carObjects, out UnifiedObject[] bogieObjects, out double[] axleLocations, out TrainManager.Train train, bool loadObjects) { CultureInfo Culture = CultureInfo.InvariantCulture; carObjects = new UnifiedObject[] { }; bogieObjects = new UnifiedObject[] { }; axleLocations = new double[] { }; train = new TrainManager.Train(); if (!System.IO.File.Exists(filePath)) { return; } train.Cars = new TrainManager.Car[] { }; bool[] carObjectsReversed = new bool[train.Cars.Length]; bool[] bogieObjectsReversed = new bool[train.Cars.Length * 2]; bool[] carsDefined = new bool[train.Cars.Length]; bool[] bogiesDefined = new bool[train.Cars.Length * 2]; axleLocations = new double[train.Cars.Length * 2]; string trainPath = System.IO.Path.GetDirectoryName(filePath); System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.InvariantCulture; TextEncoding.Encoding newEncoding = TextEncoding.GetEncodingFromFile(filePath); if (newEncoding != TextEncoding.Encoding.Unknown) { switch (newEncoding) { case TextEncoding.Encoding.Utf7: encoding = Encoding.UTF7; break; case TextEncoding.Encoding.Utf8: encoding = Encoding.UTF8; break; case TextEncoding.Encoding.Utf16Le: encoding = Encoding.Unicode; break; case TextEncoding.Encoding.Utf16Be: encoding = Encoding.BigEndianUnicode; break; case TextEncoding.Encoding.Utf32Le: encoding = Encoding.UTF32; break; case TextEncoding.Encoding.Utf32Be: encoding = Encoding.GetEncoding(12001); break; case TextEncoding.Encoding.Shift_JIS: encoding = Encoding.GetEncoding(932); break; } } string[] lines = System.IO.File.ReadAllLines(filePath, encoding); for (int i = 0; i < lines.Length; i++) { int j = lines[i].IndexOf(';'); if (j >= 0) { lines[i] = lines[i].Substring(0, j).Trim(new char[] { }); } else { lines[i] = lines[i].Trim(new char[] { }); } } for (int i = 0; i < lines.Length; i++) { if (lines[i].Length != 0) { switch (lines[i].ToLowerInvariant()) { case "[exterior]": // exterior i++; while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal)) { if (lines[i].Length != 0) { int j = lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = lines[i].Substring(j + 1).TrimStart(new char[] { }); int n; if (int.TryParse(a, System.Globalization.NumberStyles.Integer, culture, out n)) { if (n >= 0) { if (n >= train.Cars.Length) { Array.Resize(ref train.Cars, n + 1); train.Cars[n] = new TrainManager.Car(train); Array.Resize(ref carObjects, n + 1); Array.Resize(ref bogieObjects, (n + 1) * 2); Array.Resize(ref carObjectsReversed, n + 1); Array.Resize(ref bogieObjectsReversed, (n + 1) * 2); Array.Resize(ref carsDefined, n + 1); Array.Resize(ref bogiesDefined, (n + 1) * 2); Array.Resize(ref axleLocations, (n + 1) * 2); } if (Path.ContainsInvalidChars(b)) { Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(culture) + " in file " + filePath); } else { string file = OpenBveApi.Path.CombineFile(trainPath, b); if (System.IO.File.Exists(file)) { if (loadObjects) { carObjects[n] = ObjectManager.LoadObject(file, encoding, false); } } else { Interface.AddMessage(MessageType.Error, true, "The car object " + file + " does not exist at line " + (i + 1).ToString(culture) + " in file " + filePath); } } } else { Interface.AddMessage(MessageType.Error, false, "The car index " + a + " does not reference an existing car at line " + (i + 1).ToString(culture) + " in file " + filePath); } } else { Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(culture) + " in file " + filePath); } } else { Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath); } } i++; } i--; break; default: if (lines[i].StartsWith("[car", StringComparison.OrdinalIgnoreCase) & lines[i].EndsWith("]", StringComparison.Ordinal)) { // car string t = lines[i].Substring(4, lines[i].Length - 5); int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, culture, out n)) { if (n >= 0) { if (n >= train.Cars.Length) { Array.Resize(ref train.Cars, n + 1); train.Cars[n] = new TrainManager.Car(train); Array.Resize(ref carObjects, n + 1); Array.Resize(ref bogieObjects, (n + 1) * 2); Array.Resize(ref carObjectsReversed, n + 1); Array.Resize(ref bogieObjectsReversed, (n + 1) * 2); Array.Resize(ref carsDefined, n + 1); Array.Resize(ref bogiesDefined, (n + 1) * 2); Array.Resize(ref axleLocations, (n + 1) * 2); } if (carsDefined[n]) { Interface.AddMessage(MessageType.Error, false, "Car " + n.ToString(culture) + " has already been declared at line " + (i + 1).ToString(culture) + " in file " + filePath); } carsDefined[n] = true; i++; while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal)) { if (lines[i].Length != 0) { int j = lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = lines[i].Substring(j + 1).TrimStart(new char[] { }); switch (a.ToLowerInvariant()) { case "object": if (string.IsNullOrEmpty(b)) { Interface.AddMessage(MessageType.Error, true, "An empty car object was supplied at line " + (i + 1).ToString(culture) + " in file " + filePath); break; } if (Path.ContainsInvalidChars(b)) { Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(culture) + " in file " + filePath); } else { string file = OpenBveApi.Path.CombineFile(trainPath, b); if (System.IO.File.Exists(file)) { if (loadObjects) { carObjects[n] = ObjectManager.LoadObject(file, encoding, false); } } else { Interface.AddMessage(MessageType.Error, true, "The car object " + file + " does not exist at line " + (i + 1).ToString(culture) + " in file " + filePath); } } break; case "length": { double m; if (double.TryParse(b, System.Globalization.NumberStyles.Float, culture, out m)) { if (m > 0.0) { train.Cars[n].Length = m; } else { Interface.AddMessage(MessageType.Error, false, "Value is expected to be a positive floating-point number in " + a + " at line " + (i + 1).ToString(culture) + " in file " + filePath); } } else { Interface.AddMessage(MessageType.Error, false, "Value is expected to be a positive floating-point number in " + a + " at line " + (i + 1).ToString(culture) + " in file " + filePath); } } break; case "reversed": carObjectsReversed[n] = b.Equals("true", StringComparison.OrdinalIgnoreCase); break; case "axles": int k = b.IndexOf(','); if (k >= 0) { string c = b.Substring(0, k).TrimEnd(new char[] { }); string d = b.Substring(k + 1).TrimStart(new char[] { }); double rear, front; if (!double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear)) { Interface.AddMessage(MessageType.Error, false, "Rear is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath); } else if (!double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front)) { Interface.AddMessage(MessageType.Error, false, "Front is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath); } else if (rear >= front) { Interface.AddMessage(MessageType.Error, false, "Rear is expected to be less than Front in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath); } else { if (n == 0) { axleLocations[n] = rear; axleLocations[n + 1] = front; } else { axleLocations[n * 2] = rear; axleLocations[n * 2 + 1] = front; } } } else { Interface.AddMessage(MessageType.Error, false, "An argument-separating comma is expected in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath); } break; default: Interface.AddMessage(MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath); break; } } else { Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath); } } i++; } i--; } else { Interface.AddMessage(MessageType.Error, false, "The car index " + t + " does not reference an existing car at line " + (i + 1).ToString(culture) + " in file " + filePath); } } else { Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(culture) + " in file " + filePath); } } else if (lines[i].StartsWith("[bogie", StringComparison.OrdinalIgnoreCase) & lines[i].EndsWith("]", StringComparison.Ordinal)) { // car string t = lines[i].Substring(6, lines[i].Length - 7); int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, culture, out n)) { if (n >= train.Cars.Length * 2) { Array.Resize(ref train.Cars, n / 2 + 1); if (n == 0) { train.Cars[0] = new TrainManager.Car(train); Array.Resize(ref axleLocations, 2); } else { train.Cars[n / 2] = new TrainManager.Car(train); Array.Resize(ref axleLocations, ((n / 2) + 1) * 2); } Array.Resize(ref carObjects, n / 2 + 1); Array.Resize(ref bogieObjects, n + 2); Array.Resize(ref carObjectsReversed, n / 2 + 1); Array.Resize(ref bogieObjectsReversed, n + 2); Array.Resize(ref carsDefined, n / 2 + 1); Array.Resize(ref bogiesDefined, n + 2); } if (n > bogiesDefined.Length - 1) { continue; } if (bogiesDefined[n]) { Interface.AddMessage(MessageType.Error, false, "Bogie " + n.ToString(culture) + " has already been declared at line " + (i + 1).ToString(culture) + " in file " + filePath); } bogiesDefined[n] = true; //Assuming that there are two bogies per car if (n >= 0 & n < train.Cars.Length * 2) { i++; while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal)) { if (lines[i].Length != 0) { int j = lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = lines[i].Substring(j + 1).TrimStart(new char[] { }); switch (a.ToLowerInvariant()) { case "object": if (Path.ContainsInvalidChars(b)) { Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(culture) + " in file " + filePath); } else { if (string.IsNullOrEmpty(b)) { Interface.AddMessage(MessageType.Error, true, "An empty bogie object was supplied at line " + (i + 1).ToString(culture) + " in file " + filePath); break; } string file = OpenBveApi.Path.CombineFile(trainPath, b); if (System.IO.File.Exists(file)) { if (loadObjects) { bogieObjects[n] = ObjectManager.LoadObject(file, encoding, false); } } else { Interface.AddMessage(MessageType.Error, true, "The bogie object " + file + " does not exist at line " + (i + 1).ToString(culture) + " in file " + filePath); } } break; case "length": { Interface.AddMessage(MessageType.Error, false, "A defined length is not supported for bogies at line " + (i + 1).ToString(culture) + " in file " + filePath); } break; case "reversed": bogieObjectsReversed[n] = b.Equals("true", StringComparison.OrdinalIgnoreCase); break; case "axles": //Axles aren't used in bogie positioning, just in rotation break; default: Interface.AddMessage(MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath); break; } } else { Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath); } } i++; } i--; } else { Interface.AddMessage(MessageType.Error, false, "The car index " + t + " does not reference an existing car at line " + (i + 1).ToString(culture) + " in file " + filePath); } } else { Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(culture) + " in file " + filePath); } } else if (lines[i].StartsWith("[coupler", StringComparison.OrdinalIgnoreCase) & lines[i].EndsWith("]", StringComparison.Ordinal)) { i++; while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal)) { /* * Coupler statments are currently not supported in Object Viewer */ i++; } i--; } else { // default if (lines.Length == 1 && encoding.Equals(Encoding.Unicode)) { /* * If only one line, there's a good possibility that our file is NOT Unicode at all * and that the misdetection has turned it into garbage * * Try again with ASCII instead */ ParseExtensionsConfig(filePath, Encoding.GetEncoding(1252), out carObjects, out bogieObjects, out axleLocations, out train, loadObjects); return; } Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath); } break; } } } // check for car objects and reverse if necessary int carObjectsCount = 0; for (int i = 0; i < train.Cars.Length; i++) { if (carObjects[i] != null) { carObjectsCount++; if (carObjectsReversed[i] && loadObjects) { if (carObjects[i] is StaticObject) { StaticObject obj = (StaticObject)carObjects[i]; obj.ApplyScale(-1.0, 1.0, -1.0); } else if (carObjects[i] is AnimatedObjectCollection) { AnimatedObjectCollection obj = (AnimatedObjectCollection)carObjects[i]; for (int j = 0; j < obj.Objects.Length; j++) { for (int h = 0; h < obj.Objects[j].States.Length; h++) { obj.Objects[j].States[h].Prototype.ApplyScale(-1.0, 1.0, -1.0); Matrix4D t = obj.Objects[j].States[h].Translation; t.Row3.X *= -1.0f; t.Row3.Z *= -1.0f; obj.Objects[j].States[h].Translation = t; } obj.Objects[j].TranslateXDirection.X *= -1.0; obj.Objects[j].TranslateXDirection.Z *= -1.0; obj.Objects[j].TranslateYDirection.X *= -1.0; obj.Objects[j].TranslateYDirection.Z *= -1.0; obj.Objects[j].TranslateZDirection.X *= -1.0; obj.Objects[j].TranslateZDirection.Z *= -1.0; } } else { throw new NotImplementedException(); } } } } //Check for bogie objects and reverse if necessary..... int bogieObjectsCount = 0; for (int i = 0; i < train.Cars.Length * 2; i++) { if (bogieObjects[i] != null) { bogieObjectsCount++; if (bogieObjectsReversed[i] && loadObjects) { if (bogieObjects[i] is StaticObject) { StaticObject obj = (StaticObject)bogieObjects[i]; obj.ApplyScale(-1.0, 1.0, -1.0); } else if (bogieObjects[i] is AnimatedObjectCollection) { AnimatedObjectCollection obj = (AnimatedObjectCollection)bogieObjects[i]; for (int j = 0; j < obj.Objects.Length; j++) { for (int h = 0; h < obj.Objects[j].States.Length; h++) { obj.Objects[j].States[h].Prototype.ApplyScale(-1.0, 1.0, -1.0); Matrix4D t = obj.Objects[j].States[h].Translation; t.Row3.X *= -1.0f; t.Row3.Z *= -1.0f; obj.Objects[j].States[h].Translation = t; } obj.Objects[j].TranslateXDirection.X *= -1.0; obj.Objects[j].TranslateXDirection.Z *= -1.0; obj.Objects[j].TranslateYDirection.X *= -1.0; obj.Objects[j].TranslateYDirection.Z *= -1.0; obj.Objects[j].TranslateZDirection.X *= -1.0; obj.Objects[j].TranslateZDirection.Z *= -1.0; } } else { throw new NotImplementedException(); } } } } if (carObjectsCount > 0 & carObjectsCount < train.Cars.Length) { Interface.AddMessage(MessageType.Warning, false, "An incomplete set of exterior objects was provided in file " + filePath); } if (bogieObjectsCount > 0 & bogieObjectsCount < train.Cars.Length * 2) { Interface.AddMessage(MessageType.Warning, false, "An incomplete set of bogie objects was provided in file " + filePath); } }
public override void TransformMe(TransformConfig config, Matrix4D matrix) { this.TransformMe(config, matrix, (CommandGroup)null); }
public static void TransformRotationZ(TriMesh mesh, double angle)//根据角度绕Z轴旋转 { Matrix4D m = ComputeMatrixRotationZ(angle); TransformationTriMesh(mesh, m); }