private void TransformAxis(TMat4x4 Mat) { TransformedAxisPointA = Mat.MulVertex(OriginalAxisPointA); TransformedAxisPointB = Mat.MulVertex(OriginalAxisPointB); }
// Perform rendering on a specific context public void Render(CRenderContext Context) { if (!Visible) { return; } // Calculate transform matrix TMat4x4 Mat = GetTransformMatrix(Context); // Calculate the inverse matrix TMat4x4 InverseMat = Mat.FindInverseMat(); // Clear translation effect InverseMat.ClearTranslation(); // Calculate the viewer position in object coordinates TVertex ViewDirection = Context.GetViewDirection(); TVertex ViewerPosInObjCoords = InverseMat.MulVertex(ViewDirection); float PerspectiveFactor = Context.GetPerspectiveFactor(); Color IlluminatedFaceColor; foreach (TFace3D Face in FaceTable) { bool FaceVisible; float FaceDotProd = 0; if (!Context.IsBackfaceCullingMode()) { // No backface culling, the face is always visible FaceVisible = true; } else { // Do backface culling FaceDotProd = Math3D.DotProduct(ViewerPosInObjCoords, Face.Normal); // Perspective mode if (Context.IsPerspectiveMode()) { // Remember if the face is visible FaceVisible = (FaceDotProd > THRESHOLD_FOR_CULLING); } else { FaceVisible = (FaceDotProd > 0); } } if (FaceVisible) { // Get current face vertices and transform to world coordinates TVertex[] FaceVertex = new TVertex[3] { Mat.MulVertex(VertexTable[Face.AIndex]), Mat.MulVertex(VertexTable[Face.BIndex]), Mat.MulVertex(VertexTable[Face.CIndex]) }; Point[] ScreenCoords = new Point[3]; if (TestForBackClipping(FaceVertex[0], FaceVertex[1], FaceVertex[2])) { bool PreventFaceDraw = false; // Perspective mode if (Context.IsPerspectiveMode()) { // Transform the from world coordinates to screen coordinates for (int i = 0; i < 3; i++) { if (Math.Abs(FaceVertex[i].Z) < POLYGON_Z_MIN_VALUE) { PreventFaceDraw = true; break; } ScreenCoords[i].X = (int)(FaceVertex[i].X * PerspectiveFactor / FaceVertex[i].Z); ScreenCoords[i].Y = (int)(FaceVertex[i].Y * PerspectiveFactor / FaceVertex[i].Z); if ((Math.Abs(ScreenCoords[i].X) > POLYGON_COORD_MAX_VALUE) || (Math.Abs(ScreenCoords[i].Y) > POLYGON_COORD_MAX_VALUE)) { PreventFaceDraw = true; break; } } } else // Orthogonal projection { PreventFaceDraw = false; // Transform the from world coordinates to screen coordinates for (int i = 0; i < 3; i++) { ScreenCoords[i].X = (int)(FaceVertex[i].X / ORTHO_PROJECTION_SCALING); ScreenCoords[i].Y = (int)(FaceVertex[i].Y / ORTHO_PROJECTION_SCALING); } } if (!PreventFaceDraw) { T2DTriangle ScreenTriangle = new T2DTriangle(ScreenCoords[0], ScreenCoords[1], ScreenCoords[2]); if (Context.IsWireFrameMode()) { Context.DrawTriangle(ScreenTriangle); } else // Filled triangles mode { float LightLevel = FaceDotProd + MIN_LIGHT_LEVEL; // Clip to maximum light level if (LightLevel > 1.0) { LightLevel = 1.0f; } // Calculate face color int ARGBColor = ClipColorChn(Face.Color.R, LightLevel); ARGBColor |= ClipColorChn(Face.Color.G, LightLevel) << 8; ARGBColor |= ClipColorChn(Face.Color.B, LightLevel) << 16; // Set maximum alpha channel value ARGBColor = (int)((uint)ARGBColor | 0xff000000); IlluminatedFaceColor = Color.FromArgb(ARGBColor); // Calculate factors for the polygon filling routine TVertex FaceNormal = Math3D.CalcFaceNormal(FaceVertex[0], FaceVertex[1], FaceVertex[2]); float M, N, K; CalculatePolygonFactors(FaceNormal, FaceVertex[1], PerspectiveFactor, out M, out N, out K); TriangleFiller.DrawFilledTriangle(ScreenTriangle, Context, IlluminatedFaceColor, M, N, K); } } } } } RenderChildObjects(Context); }
public TVertex TransformVertex(TVertex v) { return(CombinedMatrix.MulVertex(v)); }