public void Initialize(List<Vector> vertex) { triangles = new SceneTriangle[2]; Vector center = new Vector(); foreach (Vector v in vertex) center += v; center = center / 4.0f; this.Center = center; this.PlaneNormal = Vector.Cross3(vertex[1] - vertex[0], vertex[2] - vertex[0]); this.PlaneNormal.Normalize3(); SceneTriangle t1 = new SceneTriangle(); SceneTriangle t2 = new SceneTriangle(); triangles[0] = t1; triangles[1] = t2; t1.Vertex = new List<Vector>(); t2.Vertex = new List<Vector>(); t1.Vertex.Add(vertex[0]); t1.Vertex.Add(vertex[1]); t1.Vertex.Add(vertex[2]); t2.Vertex.Add(vertex[2]); t2.Vertex.Add(vertex[3]); t2.Vertex.Add(vertex[0]); t1.Materials = new List<SceneMaterial>(); t2.Materials = new List<SceneMaterial>(); t1.U = new List<float>(); t2.U = new List<float>(); t1.V = new List<float>(); t2.V = new List<float>(); for (int i = 0; i < 3; i++) { t1.Materials.Add(this.material); t2.Materials.Add(this.material); t1.U.Add(0); t1.V.Add(0); t2.U.Add(0); t2.V.Add(0); } this.Vertex = vertex; }
private void ProcessTriangle(SceneTriangle sceneTriangle, bool bilinear) { SceneMaterial sceneMat; // Set Transformations Gl.glTranslatef(sceneTriangle.Position.x, sceneTriangle.Position.y, sceneTriangle.Position.z); Gl.glRotatef(sceneTriangle.Rotation.x, 1.0f, 0.0f, 0.0f); Gl.glRotatef(sceneTriangle.Rotation.y, 0.0f, 1.0f, 0.0f); Gl.glRotatef(sceneTriangle.Rotation.z, 0.0f, 0.0f, 1.0f); Gl.glScalef(sceneTriangle.Scale.x, sceneTriangle.Scale.y, sceneTriangle.Scale.z); //Gl.glEnable(Gl.GL_TEXTURE_2D); // Specular Properties set before glBegin () sceneMat = sceneTriangle.Materials[0]; Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, MathUtils.GetVector3Array(sceneMat.Specular)); Gl.glMaterialf(Gl.GL_FRONT, Gl.GL_SHININESS, sceneMat.Shininess); // Draw the Triangle and set materials for each vertex as well Gl.glBegin(Gl.GL_TRIANGLES); Gl.glColor3fv(MathUtils.GetVector3Array(sceneMat.Diffuse)); Gl.glTexCoord2f(sceneTriangle.U[0], sceneTriangle.V[0]); Gl.glNormal3f(sceneTriangle.Normal[0].x, sceneTriangle.Normal[0].y, sceneTriangle.Normal[0].z); Gl.glVertex3f(sceneTriangle.Vertex[0].x, sceneTriangle.Vertex[0].y, sceneTriangle.Vertex[0].z); sceneMat = sceneTriangle.Materials[1]; Gl.glColor3fv(MathUtils.GetVector3Array(sceneMat.Diffuse)); Gl.glTexCoord2f(sceneTriangle.U[1], sceneTriangle.V[1]); Gl.glNormal3f(sceneTriangle.Normal[1].x, sceneTriangle.Normal[1].y, sceneTriangle.Normal[1].z); Gl.glVertex3f(sceneTriangle.Vertex[1].x, sceneTriangle.Vertex[1].y, sceneTriangle.Vertex[1].z); sceneMat = sceneTriangle.Materials[2]; Gl.glColor3fv(MathUtils.GetVector3Array(sceneMat.Diffuse)); Gl.glTexCoord2f(sceneTriangle.U[2], sceneTriangle.V[2]); Gl.glNormal3f(sceneTriangle.Normal[2].x, sceneTriangle.Normal[2].y, sceneTriangle.Normal[2].z); Gl.glVertex3f(sceneTriangle.Vertex[2].x, sceneTriangle.Vertex[2].y, sceneTriangle.Vertex[2].z); Gl.glEnd(); }
//Loads a scene from an XML file public void Load(string file) { XDocument xmlDoc = XDocument.Load(file); XElement xmlScene = xmlDoc.Elements("scene").First(); //Loading background XElement xmlBackground = xmlScene.Elements("background").First(); background.AmbientLight = LoadColor(xmlBackground.Elements("ambientLight").First()); background.Color = LoadColor(xmlBackground.Elements("color").First()); //Loading camera XElement xmlCamera = xmlScene.Elements("camera").FirstOrDefault(); if (xmlCamera != null) { SceneCamera camera = new SceneCamera(); camera.FieldOfView = LoadFloat(xmlCamera, "fieldOfView"); camera.NearClip = LoadFloat(xmlCamera, "nearClip"); camera.FarClip = LoadFloat(xmlCamera, "farClip"); camera.Position = LoadXYZ(xmlCamera.Elements("position").First()); camera.Target = LoadXYZ(xmlCamera.Elements("target").First()); camera.Up = LoadXYZ(xmlCamera.Elements("up").First()); cameras.Add(camera); } XElement xmlCameras = xmlScene.Elements("camera_list").FirstOrDefault(); if (xmlCameras != null) { foreach (XElement cameraNode in xmlCameras.Elements("camera")) { SceneCamera camera = new SceneCamera(); camera.FieldOfView = LoadFloat(cameraNode, "fieldOfView"); camera.NearClip = LoadFloat(cameraNode, "nearClip"); camera.FarClip = LoadFloat(cameraNode, "farClip"); camera.Position = LoadXYZ(cameraNode.Elements("position").First()); camera.Target = LoadXYZ(cameraNode.Elements("target").First()); camera.Up = LoadXYZ(cameraNode.Elements("up").First()); cameras.Add(camera); } } XElement xmlLights = xmlScene.Elements("light_list").First(); foreach (XElement lightNode in xmlLights.Elements("light")) { SceneLight lightObj = new SceneLight(); lightObj.Position = LoadXYZ(lightNode.Elements("position").First()); if (lightNode.Elements("a").Any()) lightObj.A = LoadXYZ(lightNode.Elements("a").First()); if (lightNode.Elements("b").Any()) lightObj.B = LoadXYZ(lightNode.Elements("b").First()); lightObj.Color = LoadColor(lightNode.Elements("color").First()); XElement atenuationNode = lightNode.Elements("attenuation").First(); lightObj.AtenuationConstant = LoadFloat(atenuationNode, "constant"); lightObj.AtenuationLinear = LoadFloat(atenuationNode, "linear"); lightObj.AtenuationQuadratic = LoadFloat(atenuationNode, "quadratic"); lights.Add(lightObj); } XElement xmlMaterials = xmlScene.Elements("material_list").First(); foreach (XElement materialNode in xmlMaterials.Elements("material")) { string name = materialNode.Attribute("name").Value; SceneMaterial material = new SceneMaterial(); material.Name = name; if (materialNode.Elements("texture").Any()) material.TextureFile = materialNode.Elements("texture").First().Attribute("filename").Value; if (material.TextureFile != null && material.TextureFile != String.Empty && File.Exists(material.TextureFile)) material.TextureImage = (Bitmap)Bitmap.FromFile(material.TextureFile); if (materialNode.Elements("bumpmap").Any()) material.BumpFile = materialNode.Elements("bumpmap").First().Attribute("filename").Value; if (material.BumpFile != null && material.BumpFile != String.Empty && File.Exists(material.BumpFile)) material.BumpImage = (Bitmap)Bitmap.FromFile(material.BumpFile); if (materialNode.Elements("normalmap").Any()) material.NormalFile = materialNode.Elements("normalmap").First().Attribute("filename").Value; if (material.NormalFile != null && material.NormalFile != String.Empty && File.Exists(material.NormalFile)) material.NormalImage = (Bitmap)Bitmap.FromFile(material.NormalFile); if (materialNode.Elements("specular").Any()) material.Specular = LoadSpecular(materialNode.Elements("specular").First()); if (materialNode.Elements("diffuse").Any()) material.Diffuse = LoadColor(materialNode.Elements("diffuse").First()); if (materialNode.Elements("transparent").Any()) material.Transparent = LoadColor(materialNode.Elements("transparent").First()); if (materialNode.Elements("reflective").Any()) material.Reflective = LoadColor(materialNode.Elements("reflective").First()); if (materialNode.Elements("refraction_index").Any()) material.RefractionIndex = LoadColor(materialNode.Elements("refraction_index").First()); if (materialNode.Elements("refractiveness").Any()) material.Refractiveness = LoadColor(materialNode.Elements("refractiveness").First()); materialsTable.Add(name, material); } XElement xmlObjects = xmlScene.Elements("object_list").First(); foreach (XElement modelNode in xmlObjects.Elements("model")) { SceneModel model = new SceneModel(modelNode.Attribute("name").Value, modelNode.Attribute("path").Value); XDocument xmlModel = XDocument.Load(model.FileName); XElement xmlSceneModel = xmlModel.Elements("model").First(); model.Scale = LoadXYZ(modelNode.Elements("scale").First()); model.Position = LoadXYZ(modelNode.Elements("position").First()); model.Rotation = LoadXYZ(modelNode.Elements("rotation").First()); XElement xmlTriangles = xmlSceneModel.Elements("triangle_list").First(); foreach (XElement triangleNode in xmlTriangles.Elements("triangle")) { SceneTriangle triangle = new SceneTriangle(); triangle.Scale = LoadXYZ(triangleNode.Elements("scale").First()); triangle.Position = LoadXYZ(triangleNode.Elements("position").First()); triangle.Rotation = LoadXYZ(triangleNode.Elements("rotation").First()); foreach (XElement vertexNode in triangleNode.Elements("vertex")) { triangle.Materials.Add(materialsTable[vertexNode.Attribute("material").Value]); triangle.Vertex.Add(LoadXYZ(vertexNode.Elements("position").First())); triangle.Normal.Add(LoadXYZ(vertexNode.Elements("normal").First())); XElement textNode = vertexNode.Elements("texture").First(); triangle.U.Add(LoadFloat(textNode, "u")); triangle.V.Add(LoadFloat(textNode, "v")); } model.Triangles.Add(triangle); } objects.Add(model); } foreach (XElement triangleNode in xmlObjects.Elements("triangle")) { SceneTriangle triangle = new SceneTriangle(); triangle.Scale = LoadXYZ(triangleNode.Elements("scale").First()); triangle.Position = LoadXYZ(triangleNode.Elements("position").First()); triangle.Rotation = LoadXYZ(triangleNode.Elements("rotation").First()); foreach (XElement vertexNode in triangleNode.Elements("vertex")) { triangle.Materials.Add(materialsTable[vertexNode.Attribute("material").Value]); triangle.Vertex.Add(LoadXYZ(vertexNode.Elements("position").First())); triangle.Normal.Add(LoadXYZ(vertexNode.Elements("normal").First())); XElement textNode = vertexNode.Elements("texture").First(); triangle.U.Add(LoadFloat(textNode, "u")); triangle.V.Add(LoadFloat(textNode, "v")); } objects.Add(triangle); } foreach (XElement sphereNode in xmlObjects.Elements("sphere")) { SceneSphere sphere = new SceneSphere(); sphere.Radius = LoadFloat(sphereNode, "radius"); sphere.Material = materialsTable[sphereNode.Attribute("material").Value]; sphere.Scale = LoadXYZ(sphereNode.Elements("scale").First()); sphere.Position = LoadXYZ(sphereNode.Elements("position").First()); sphere.Rotation = LoadXYZ(sphereNode.Elements("rotation").First()); sphere.Center = LoadXYZ(sphereNode.Elements("center").First()); sphere.Velocity = LoadXYZ(sphereNode.Elements("velocity").FirstOrDefault()); objects.Add(sphere); } foreach (XElement cylinderNode in xmlObjects.Elements("cylinder")) { SceneCylinder cylinder = new SceneCylinder(); cylinder.Radius = LoadFloat(cylinderNode, "radius"); cylinder.Material = materialsTable[cylinderNode.Attribute("material").Value]; cylinder.Scale = LoadXYZ(cylinderNode.Elements("scale").First()); cylinder.Position = LoadXYZ(cylinderNode.Elements("position").First()); cylinder.Rotation = LoadXYZ(cylinderNode.Elements("rotation").First()); cylinder.BasePoint = LoadXYZ(cylinderNode.Elements("base").First()); cylinder.EndPoint = LoadXYZ(cylinderNode.Elements("end").First()); //cylinder.Velocity = LoadXYZ(cylinderNode.Elements("velocity").FirstOrDefault()); objects.Add(cylinder); } foreach (XElement planeNode in xmlObjects.Elements("plane")) { Plane plane = new Plane(); plane.Material = materialsTable[planeNode.Attribute("material").Value]; plane.Height = LoadFloat(planeNode, "height"); plane.Width = LoadFloat(planeNode, "width"); plane.Scale = LoadXYZ(planeNode.Elements("scale").First()); plane.Position = LoadXYZ(planeNode.Elements("position").First()); plane.Rotation = LoadXYZ(planeNode.Elements("rotation").First()); plane.Center = LoadXYZ(planeNode.Elements("center").First()); plane.L1 = LoadXYZ(planeNode.Elements("l1").First()); plane.L2 = LoadXYZ(planeNode.Elements("l2").First()); plane.Initialize(); objects.Add(plane); } foreach (XElement tableNode in xmlObjects.Elements("table")) { SceneTable table = new SceneTable(); table.Material = materialsTable[tableNode.Attribute("material").Value]; table.Height = LoadFloat(tableNode, "height"); table.Width = LoadFloat(tableNode, "width"); table.Scale = LoadXYZ(tableNode.Elements("scale").First()); table.Position = LoadXYZ(tableNode.Elements("position").First()); table.Rotation = LoadXYZ(tableNode.Elements("rotation").First()); table.Radius = LoadFloat(tableNode, "radius"); XElement planeNode = tableNode.Elements("plane").First(); Plane plane = new Plane(); plane.Material = table.Material; plane.Height = LoadFloat(planeNode, "height"); plane.Width = LoadFloat(planeNode, "width"); plane.Scale = LoadXYZ(planeNode.Elements("scale").First()); plane.Position = LoadXYZ(planeNode.Elements("position").First()); plane.Rotation = LoadXYZ(planeNode.Elements("rotation").First()); plane.Center = LoadXYZ(planeNode.Elements("center").First()); plane.L1 = LoadXYZ(planeNode.Elements("l1").First()); plane.L2 = LoadXYZ(planeNode.Elements("l2").First()); plane.Initialize(); table.Initialize(plane); objects.Add(table); } }
public void Initialize() { L1.Normalize3(); L1 = L1 * Width; L2.Normalize3(); L2 = L2 * Height; PlaneNormal = Vector.Cross3(L1, L2); PlaneNormal.Normalize3(); Vertex = new List<Vector>(); triangles = new SceneTriangle[2]; Vector A = Center + L1 + L2; Vector B = Center + L1 - L2; Vector C = Center - L1 - L2; Vector D = Center - L1 + L2; Vertex.Add(A); Vertex.Add(B); Vertex.Add(C); Vertex.Add(D); SceneTriangle t1 = new SceneTriangle(); SceneTriangle t2 = new SceneTriangle(); triangles[0] = t1; triangles[1] = t2; t1.Vertex = new List<Vector>(); t2.Vertex = new List<Vector>(); t1.Vertex.Add(A); t1.Vertex.Add(B); t1.Vertex.Add(C); t2.Vertex.Add(C); t2.Vertex.Add(D); t2.Vertex.Add(A); t1.Materials = new List<SceneMaterial>(); t2.Materials = new List<SceneMaterial>(); t1.U = new List<float>(); t2.U = new List<float>(); t1.V = new List<float>(); t2.V = new List<float>(); for (int i = 0; i < 3; i++) { t1.Materials.Add(this.material); t2.Materials.Add(this.material); t1.U.Add(0); t1.V.Add(0); t2.U.Add(0); t2.V.Add(0); } }
private List<SceneTriangle> ClipFrustrum() { List<SceneTriangle> clippedTriangles = new List<SceneTriangle>(); foreach (SceneObject sceneObj in scene.Objects) clippedTriangles.Add(sceneObj as SceneTriangle); Vector w = CalculateW(scene.Camera.Position, scene.Camera.Target); Vector q = scene.Camera.Position - scene.Camera.NearClip * w; //Para efectos del clipping plane // float D = -Vector.Dot3(w, scene.Camera.Position) + scene.Camera.NearClip * Vector.Dot3(w, w); Console.WriteLine("Z: " + scene.Camera.Position.z); //Console.WriteLine("q: " + q); //Console.WriteLine("w: " + w); planeNormals.Clear(); planePoints.Clear(); planeNames.Clear(); planeNormals.Add(-w); planePoints.Add(scene.Camera.Position - w * scene.Camera.NearClip); planeNormals.Add(w); planePoints.Add(scene.Camera.Position - w * scene.Camera.FarClip); planeNames.Add("Near"); planeNames.Add("Far"); Console.WriteLine("////////////////////////////////////////////////////////"); Console.WriteLine("Num triangles: " + clippedTriangles.Count); Console.WriteLine("Num planes: " + planeNormals.Count); Console.WriteLine("Z: " + scene.Camera.Position.z); for (int current_plane = 0; current_plane < planeNormals.Count; current_plane++) { Console.WriteLine("Plane: " + planeNames[current_plane]); // Cons float D = -Vector.Dot3(planeNormals[current_plane], planePoints[current_plane]); List<SceneTriangle> newTriangles = new List<SceneTriangle>(); foreach (SceneTriangle triangle in clippedTriangles) { List<Fragment> outside = new List<Fragment>(); List<Fragment> inside = new List<Fragment>(); for (int i = 0; i < 3; ++i) { float x = triangle.Vertex[i].x, y = triangle.Vertex[i].y, z = triangle.Vertex[i].z; float planeDistance = Vector.Dot3(planeNormals[current_plane], triangle.Vertex[i]) + D; //Console.WriteLine("Vertex: " + triangle.Vertex[i]); Console.WriteLine("Distance: " + planeDistance); if (planeDistance < 0) { Fragment outsideVertex = new Fragment(); outsideVertex.U = triangle.U[i]; outsideVertex.V = triangle.V[i]; outsideVertex.Normal = triangle.Normal[i]; outsideVertex.Material = triangle.Materials[i]; outsideVertex.RasterizedPosition = triangle.Vertex[i]; outside.Add(outsideVertex); } else { Fragment insideVertex = new Fragment(); insideVertex.U = triangle.U[i]; insideVertex.RasterizedPosition = triangle.Vertex[i]; insideVertex.V = triangle.V[i]; insideVertex.Normal = triangle.Normal[i]; insideVertex.Material = triangle.Materials[i]; inside.Add(insideVertex); } } if (outside.Count == 3) { Console.WriteLine("All vertex outside"); continue; } else if (outside.Count == 2) { Console.WriteLine("Two vertices outside, adding new triangle"); float t1 = (Vector.Dot3(planeNormals[current_plane], outside[0].RasterizedPosition) + D) / (Vector.Dot3(planeNormals[current_plane], outside[0].RasterizedPosition - inside[0].RasterizedPosition)); Fragment inter1 = new Fragment(outside[0], inside[0], t1); Console.WriteLine("t1 = " + t1); float t2 = (Vector.Dot3(planeNormals[current_plane], outside[1].RasterizedPosition) + D) / (Vector.Dot3(planeNormals[current_plane], outside[1].RasterizedPosition - inside[0].RasterizedPosition)); Fragment inter2 = new Fragment(outside[1], inside[0], t2); Console.WriteLine("t2 = " + t2); SceneTriangle clipped = new SceneTriangle(); clipped.Vertex = new List<Vector>(); clipped.Vertex.Add(inter1.RasterizedPosition); clipped.Vertex.Add(inter2.RasterizedPosition); clipped.Vertex.Add(inside[0].RasterizedPosition); clipped.U = new List<float>(); clipped.U.Add(inter1.U); clipped.U.Add(inter2.U); clipped.U.Add(inside[0].U); clipped.V = new List<float>(); clipped.V.Add(inter1.V); clipped.V.Add(inter2.V); clipped.V.Add(inside[0].V); clipped.Normal = new List<Vector>(); clipped.Normal.Add(inter1.Normal); clipped.Normal.Add(inter2.Normal); clipped.Normal.Add(inside[0].Normal); clipped.Materials = triangle.Materials; clipped.Position = triangle.Position; clipped.Rotation = triangle.Rotation; clipped.Scale = triangle.Scale; newTriangles.Add(clipped); Console.WriteLine("New positions: "); Console.WriteLine(clipped.Vertex[0]); Console.WriteLine(clipped.Vertex[1]); Console.WriteLine(clipped.Vertex[2]); } else if (outside.Count == 1) { Console.WriteLine("One vertex outside"); float t1 = (Vector.Dot3(planeNormals[current_plane], outside[0].RasterizedPosition) + D) / (Vector.Dot3(planeNormals[current_plane], outside[0].RasterizedPosition - inside[0].RasterizedPosition)); Fragment inter1 = new Fragment(outside[0], inside[0], t1); Console.WriteLine("t1 = " + t1); float t2 = (Vector.Dot3(planeNormals[current_plane], outside[0].RasterizedPosition) + D) / (Vector.Dot3(planeNormals[current_plane], outside[0].RasterizedPosition - inside[1].RasterizedPosition)); Fragment inter2 = new Fragment(outside[0], inside[1], t2); Console.WriteLine("t2 = " + t2); SceneTriangle clipped1 = new SceneTriangle(); clipped1.Vertex = new List<Vector>(); clipped1.Vertex.Add(inter1.RasterizedPosition); clipped1.Vertex.Add(inter2.RasterizedPosition); clipped1.Vertex.Add(inside[0].RasterizedPosition); clipped1.U = new List<float>(); clipped1.U.Add(inter1.U); clipped1.U.Add(inter2.U); clipped1.U.Add(inside[0].U); clipped1.V = new List<float>(); clipped1.V.Add(inter1.V); clipped1.V.Add(inter2.V); clipped1.V.Add(inside[0].V); clipped1.Normal = new List<Vector>(); clipped1.Normal.Add(inter1.Normal); clipped1.Normal.Add(inter2.Normal); clipped1.Normal.Add(inside[0].Normal); clipped1.Materials = triangle.Materials; clipped1.Position = triangle.Position; clipped1.Rotation = triangle.Rotation; clipped1.Scale = triangle.Scale; newTriangles.Add(clipped1); SceneTriangle clipped2 = new SceneTriangle(); clipped2.Vertex = new List<Vector>(); clipped2.Vertex.Add(inter2.RasterizedPosition); clipped2.Vertex.Add(inside[0].RasterizedPosition); clipped2.Vertex.Add(inside[1].RasterizedPosition); clipped2.U = new List<float>(); clipped2.U.Add(inter2.U); clipped2.U.Add(inside[0].U); clipped2.U.Add(inside[1].U); clipped2.V = new List<float>(); clipped2.V.Add(inter2.V); clipped2.V.Add(inside[0].V); clipped2.V.Add(inside[1].V); clipped2.Normal = new List<Vector>(); clipped2.Normal.Add(inter2.Normal); clipped2.Normal.Add(inside[0].Normal); clipped2.Normal.Add(inside[1].Normal); SceneMaterial otherMat = scene.GetMaterial("Red"); clipped2.Materials.Add(otherMat); clipped2.Materials.Add(otherMat); clipped2.Materials.Add(otherMat); clipped2.Materials = triangle.Materials; clipped2.Position = triangle.Position; clipped2.Rotation = triangle.Rotation; clipped2.Scale = triangle.Scale; newTriangles.Add(clipped2); Console.WriteLine("New positions: "); Console.WriteLine(clipped1.Vertex[0]); Console.WriteLine(clipped1.Vertex[1]); Console.WriteLine(clipped1.Vertex[2]); Console.WriteLine(clipped2.Vertex[0]); Console.WriteLine(clipped2.Vertex[1]); Console.WriteLine(clipped2.Vertex[2]); } else { newTriangles.Add(triangle); } } clippedTriangles = newTriangles; } Console.WriteLine("After clipping: " + clippedTriangles.Count + " triangles"); return clippedTriangles; }