private Matrix3D GetVertexTransformationMatrix() { var rotX = 0f; var offsetZ = 0f; var scale = new Vertex3D(_data.ScaleX, _data.ScaleY, 1.0f); switch (_data.Shape) { case TriggerShape.TriggerWireB: rotX = -23.0f; break; case TriggerShape.TriggerWireC: rotX = 140.0f; offsetZ = -19.0f; break; case TriggerShape.TriggerButton: offsetZ = 5.0f; scale.X = _data.Radius; scale.Y = _data.Radius; scale.Z = _data.Radius; break; case TriggerShape.TriggerStar: scale.X = _data.Radius; scale.Y = _data.Radius; scale.Z = _data.Radius; break; } // scale matrix var scaleMatrix = new Matrix3D(); scaleMatrix.SetScaling(scale.X, scale.Y, scale.Z); // translation matrix var transMatrix = new Matrix3D(); transMatrix.SetTranslation(0f, 0f, offsetZ); // rotation matrix var rotMatrix = new Matrix3D(); rotMatrix.RotateXMatrix(MathF.DegToRad(rotX)); var fullMatrix = scaleMatrix; fullMatrix.Multiply(rotMatrix); fullMatrix.Multiply(transMatrix); return(fullMatrix); }
Matrix3D IRenderable.TransformationMatrix(Table.Table table, Origin origin) { switch (origin) { case Origin.Original: var rotMatrix = new Matrix3D().RotateZMatrix(MathF.DegToRad(Data.Orientation)); var transMatrix = new Matrix3D().SetTranslation(Data.Center.X, Data.Center.Y, 0f); return(rotMatrix.Multiply(transMatrix)); case Origin.Global: return(Matrix3D.Identity); default: throw new ArgumentOutOfRangeException(nameof(origin), origin, "Unknown origin " + origin); } }
protected override Tuple <Matrix3D, Matrix3D> GetTransformationMatrix(float height) { // scale matrix var scaleMatrix = new Matrix3D(); scaleMatrix.SetScaling(Scale.X, Scale.Y, Scale.Z); // translation matrix var transMatrix = new Matrix3D(); transMatrix.SetTranslation(Position.X, Position.Y, Position.Z + height); // translation + rotation matrix var rotTransMatrix = new Matrix3D(); rotTransMatrix.SetTranslation(_data.RotAndTra[3], _data.RotAndTra[4], _data.RotAndTra[5]); var tempMatrix = new Matrix3D(); tempMatrix.RotateZMatrix(MathF.DegToRad(_data.RotAndTra[2])); rotTransMatrix.Multiply(tempMatrix); tempMatrix.RotateYMatrix(MathF.DegToRad(_data.RotAndTra[1])); rotTransMatrix.Multiply(tempMatrix); tempMatrix.RotateXMatrix(MathF.DegToRad(_data.RotAndTra[0])); rotTransMatrix.Multiply(tempMatrix); tempMatrix.RotateZMatrix(MathF.DegToRad(_data.RotAndTra[8])); rotTransMatrix.Multiply(tempMatrix); tempMatrix.RotateYMatrix(MathF.DegToRad(_data.RotAndTra[7])); rotTransMatrix.Multiply(tempMatrix); tempMatrix.RotateXMatrix(MathF.DegToRad(_data.RotAndTra[6])); rotTransMatrix.Multiply(tempMatrix); var fullMatrix = scaleMatrix.Clone(); fullMatrix.Multiply(rotTransMatrix); fullMatrix.Multiply(transMatrix); // fullMatrix = Smatrix * RTmatrix * Tmatrix scaleMatrix.SetScaling(1.0f, 1.0f, 1f); fullMatrix.Multiply(scaleMatrix); return(new Tuple <Matrix3D, Matrix3D>(fullMatrix, null)); }
private Dictionary <string, Mesh> GenerateMeshes(float height, float margin = 0f) { var meshes = new Dictionary <string, Mesh>(); var fullMatrix = new Matrix3D(); fullMatrix.RotateZMatrix(MathF.DegToRad(180.0f)); var baseRadius = _data.BaseRadius - _data.RubberThickness + margin; var endRadius = _data.EndRadius - _data.RubberThickness + margin; // calc angle needed to fix P0 location var sinAngle = (baseRadius - endRadius) / _data.FlipperRadius; if (sinAngle > 1.0) { sinAngle = 1.0f; } if (sinAngle < -1.0) { sinAngle = -1.0f; } var fixAngle = MathF.Asin(sinAngle); var fixAngleScale = fixAngle / (float)(System.Math.PI * 0.5); // scale (in relation to 90 deg.) // fixAngleScale = 0.0; // note: if you force fixAngleScale = 0.0 then all will look as old version // lambda used to apply fix void ApplyFix(ref Vertex3DNoTex2 vert, Vertex2D center, float midAngle, float radius, Vertex2D newCenter) { var vAngle = MathF.Atan2(vert.Y - center.Y, vert.X - center.X); var nAngle = MathF.Atan2(vert.Ny, vert.Nx); // we want have angles with same sign as midAngle, fix it: if (midAngle < 0.0) { if (vAngle > 0.0) { vAngle -= (float)(System.Math.PI * 2.0); } if (nAngle > 0.0) { nAngle -= (float)(System.Math.PI * 2.0); } } else { if (vAngle < 0.0) { vAngle += (float)(System.Math.PI * 2.0); } if (nAngle < 0.0) { nAngle += (float)(System.Math.PI * 2.0); } } nAngle -= (vAngle - midAngle) * fixAngleScale * MathF.Sign(midAngle); vAngle -= (vAngle - midAngle) * fixAngleScale * MathF.Sign(midAngle); float nL = new Vertex2D(vert.Nx, vert.Ny).Length(); vert.X = MathF.Cos(vAngle) * radius + newCenter.X; vert.Y = MathF.Sin(vAngle) * radius + newCenter.Y; vert.Nx = MathF.Cos(nAngle) * nL; vert.Ny = MathF.Sin(nAngle) * nL; } // base and tip var baseMesh = new Mesh(Base, Vertices, Indices).Clone(); for (var t = 0; t < 13; t++) { for (var i = 0; i < baseMesh.Vertices.Length; i++) { var v = baseMesh.Vertices[i]; if (v.X == VertsBaseBottom[t].X && v.Y == VertsBaseBottom[t].Y && v.Z == VertsBaseBottom[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)-(System.Math.PI * 0.5), baseRadius, new Vertex2D(0, 0)); } if (v.X == VertsTipBottom[t].X && v.Y == VertsTipBottom[t].Y && v.Z == VertsTipBottom[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius, new Vertex2D(0, _data.FlipperRadius)); } if (v.X == VertsBaseTop[t].X && v.Y == VertsBaseTop[t].Y && v.Z == VertsBaseTop[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)(-System.Math.PI * 0.5), baseRadius, new Vertex2D(0, 0)); } if (v.X == VertsTipTop[t].X && v.Y == VertsTipTop[t].Y && v.Z == VertsTipTop[t].Z) { ApplyFix(ref baseMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius, new Vertex2D(0, _data.FlipperRadius)); } } } baseMesh.Transform(fullMatrix, null, z => z * _data.Height + height); meshes[Base] = baseMesh; // rubber var rubberMesh = new Mesh(Rubber, Vertices, Indices).Clone(); for (var t = 0; t < 13; t++) { for (var i = 0; i < rubberMesh.Vertices.Length; i++) { var v = rubberMesh.Vertices[i]; if (v.X == VertsBaseBottom[t].X && v.Y == VertsBaseBottom[t].Y && v.Z == VertsBaseBottom[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)(-System.Math.PI * 0.5), baseRadius + _data.RubberThickness + margin, new Vertex2D(0, 0)); } if (v.X == VertsTipBottom[t].X && v.Y == VertsTipBottom[t].Y && v.Z == VertsTipBottom[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius + _data.RubberThickness + margin, new Vertex2D(0, _data.FlipperRadius)); } if (v.X == VertsBaseTop[t].X && v.Y == VertsBaseTop[t].Y && v.Z == VertsBaseTop[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsBaseBottom[6].X, VertsBaseBottom[0].Y), (float)(-System.Math.PI * 0.5), baseRadius + _data.RubberThickness + margin, new Vertex2D(0, 0)); } if (v.X == VertsTipTop[t].X && v.Y == VertsTipTop[t].Y && v.Z == VertsTipTop[t].Z) { ApplyFix(ref rubberMesh.Vertices[i], new Vertex2D(VertsTipBottom[6].X, VertsTipBottom[0].Y), (float)(System.Math.PI * 0.5), endRadius + _data.RubberThickness + margin, new Vertex2D(0, _data.FlipperRadius)); } } } rubberMesh.Transform(fullMatrix, null, z => z * _data.RubberWidth + (height + _data.RubberHeight + margin * 10f)); meshes[Rubber] = rubberMesh; return(meshes); }