private void AddGeometryToSceneNode(Geometry geometry, float3 position) { Geometry newGeo = geometry.CloneGeometry(); newGeo.Triangulate(); JometriMesh geometryMesh = new JometriMesh(newGeo); SceneNode sceneNodeContainer = new SceneNode { Components = new List <SceneComponent>() }; Mesh meshComponent = new Mesh { Vertices = geometryMesh.Vertices, Triangles = geometryMesh.Triangles, Normals = geometryMesh.Normals, }; Transform translationComponent = new Transform { Rotation = float3.Zero, Scale = new float3(1, 1, 1), Translation = position }; sceneNodeContainer.Components.Add(translationComponent); sceneNodeContainer.Components.Add(MakeEffect.FromDiffuseSpecular(_defaultColor, float4.Zero)); sceneNodeContainer.Components.Add(meshComponent); _parentNode.Children.Add(sceneNodeContainer); _activeGeometrys.Add(_parentNode.Children.IndexOf(sceneNodeContainer), geometry); }
private void AddGeometryToSceneNode(Geometry geometry, float3 position) { Geometry newGeo = geometry.CloneGeometry(); newGeo.Triangulate(); var geometryMesh = new JometriMesh(newGeo); var sceneNodeContainer = new SceneNode { Components = new List <SceneComponent>() }; var meshComponent = new Mesh { Vertices = geometryMesh.Vertices, Triangles = geometryMesh.Triangles, Normals = geometryMesh.Normals, }; var translationComponent = new Transform { Rotation = float3.Zero, Scale = new float3(1, 1, 1), Translation = position }; var shaderEffect = ShaderCodeBuilder.Default; shaderEffect.SetEffectParam(UniformNameDeclarations.AlbedoColor, _defaultColor); sceneNodeContainer.Components.Add(translationComponent); sceneNodeContainer.Components.Add(shaderEffect); sceneNodeContainer.Components.Add(meshComponent); _parentNode.Children.Add(sceneNodeContainer); _activeGeometrys.Add(_parentNode.Children.IndexOf(sceneNodeContainer), geometry); }
private void AddGeometryToSceneNode(Geometry geometry, float3 position) { Geometry newGeo = geometry.CloneGeometry(); newGeo.Triangulate(); var geometryMesh = new JometriMesh(newGeo); var sceneNodeContainer = new SceneNodeContainer { Components = new List <SceneComponentContainer>() }; var meshComponent = new Mesh { Vertices = geometryMesh.Vertices, Triangles = geometryMesh.Triangles, Normals = geometryMesh.Normals, }; var translationComponent = new TransformComponent { Rotation = float3.Zero, Scale = new float3(1, 1, 1), Translation = position }; var materialComponent = new MaterialComponent { Diffuse = new MatChannelContainer(), Specular = new SpecularChannelContainer(), }; materialComponent.Diffuse.Color = _defaultColor; sceneNodeContainer.Components.Add(translationComponent); sceneNodeContainer.Components.Add(materialComponent); sceneNodeContainer.Components.Add(meshComponent); _parentNode.Children.Add(sceneNodeContainer); _activeGeometrys.Add(_parentNode.Children.IndexOf(sceneNodeContainer), geometry); }
// Init is called on startup. public override void Init() { var outlineOne = new PolyBoundary //CCW!! { Points = new List <float3> { new float3(1, 0, 0), new float3(1.25f, 0.5f, 0.5f), new float3(1, 1, 1), new float3(0, 1, 1), new float3(-0.25f, 0.5f, 0.5f), new float3(0, 0, 0) }, IsOuter = true }; var outlineOneHole = new PolyBoundary //CW!! { Points = new List <float3> { new float3(0.75f, 0.25f, 0.25f), new float3(0.25f, 0.25f, 0.25f), new float3(0.25f, 0.75f, 0.75f), new float3(0.75f, 0.75f, 0.75f) }, IsOuter = false }; var outlineTwo = new PolyBoundary //CCW!! { Points = new List <float3> { new float3(1, 0, 0), new float3(1, 0.707f, 0.707f), new float3(0, 0.707f, 0.707f), new float3(0, 0, 0) }, IsOuter = true }; var outlineThree = new PolyBoundary //CCW!! { Points = new List <float3> { new float3(0, 0, 0), new float3(1, 0, 1), new float3(0, 0.5f, 0.5f) }, IsOuter = true }; var geomOutlinesOne = new List <PolyBoundary> { outlineOne, outlineOneHole }; var geomOne = new Geometry(geomOutlinesOne); geomOne.Extrude2DPolygon(0.5f, true); geomOne.Triangulate(); var meshOne = new JometriMesh(geomOne); var geomCubeOutlines = new List <PolyBoundary> { outlineTwo }; var geomCube = new Geometry(geomCubeOutlines); geomCube.Extrude2DPolygon(1, false); //geomCube.Extrude2DPolygon(1, true); geomCube.Triangulate(); var cube = new JometriMesh(geomCube); var geomTriangleOutlines = new List <PolyBoundary> { outlineThree }; var geomTri = new Geometry(geomTriangleOutlines); geomTri.Triangulate(); var triangle = new JometriMesh(geomTri); ////////////////// Fill SceneNode //////////////////////////////// var parentNode = new SceneNode { Components = new List <SceneComponent>(), Children = new ChildList() }; var parentTrans = new Transform { Rotation = float3.Zero, Scale = float3.One, Translation = new float3(0, 0, 0) }; parentNode.Components.Add(parentTrans); var sceneNodeCOne = new SceneNode { Components = new List <SceneComponent>() }; var meshCOne = new Mesh { Vertices = meshOne.Vertices, Triangles = meshOne.Triangles, Normals = meshOne.Normals, }; var tranC = new Transform { Rotation = float3.Zero, Scale = float3.One, Translation = new float3(0, 0, 0) }; sceneNodeCOne.Components.Add(tranC); sceneNodeCOne.Components.Add(meshCOne); /////////////////////////////////////////////////////////// var sceneNodeCCube = new SceneNode { Components = new List <SceneComponent>() }; var meshCCube = new Mesh { Vertices = cube.Vertices, Triangles = cube.Triangles, Normals = cube.Normals, }; var tranCube = new Transform { Rotation = float3.Zero, Scale = float3.One, Translation = new float3(-2, -1, 0) }; sceneNodeCCube.Components.Add(tranCube); sceneNodeCCube.Components.Add(meshCCube); ////////////////////////////////////////////////////////////////// var sceneNodeCTri = new SceneNode { Components = new List <SceneComponent>() }; var meshCTri = new Mesh { Vertices = triangle.Vertices, Triangles = triangle.Triangles, Normals = triangle.Normals, }; var tranTri = new Transform { Rotation = float3.Zero, Scale = float3.One, Translation = new float3(1.5f, -1, 0) }; sceneNodeCTri.Components.Add(tranTri); sceneNodeCTri.Components.Add(meshCTri); ////////////////////////////////////////////////////////////////// parentNode.Children.Add(sceneNodeCTri); parentNode.Children.Add(sceneNodeCOne); parentNode.Children.Add(sceneNodeCCube); var sc = new SceneContainer { Children = new List <SceneNode> { parentNode } }; _renderer = new SceneRendererForward(sc); // Set the clear color for the back buffer to white (100% intensity in all color channels R, G, B, A). RC.ClearColor = new float4(0, 1, 1, 1); }
private void InteractionHandler() { //Add new Geometry if (Keyboard.GetKey(KeyCodes.D1) && _keyTimeout < 0) { _keyTimeout = 1; Geometry geometry = CreatePrimitiveGeometry.CreateCuboidGeometry(1, 1, 1); AddGeometryToSceneNode(geometry, new float3(0, 0, 0)); } if (Keyboard.GetKey(KeyCodes.D2) && _keyTimeout < 0) { _keyTimeout = 1; Geometry geometry = CreatePrimitiveGeometry.CreatePyramidGeometry(1, 1, 1); AddGeometryToSceneNode(geometry, new float3(0, 0, 0)); } if (Keyboard.GetKey(KeyCodes.D3) && _keyTimeout < 0) { _keyTimeout = 1; Geometry geometry = CreatePrimitiveGeometry.CreateConeGeometry(1, 1, 15); AddGeometryToSceneNode(geometry, new float3(0, 0, 0)); } if (Keyboard.GetKey(KeyCodes.D4) && _keyTimeout < 0) { _keyTimeout = 1; Geometry geometry = CreatePrimitiveGeometry.CreateSpehreGeometry(1, 30, 15); AddGeometryToSceneNode(geometry, new float3(0, 0, 0)); } _keyTimeout -= DeltaTime; //following actions are only allowed if something is selected if (_selectedNode == null) { return; } //Translate Geometry if (Keyboard.GetKey(KeyCodes.G)) { _isTranslating = true; } if (_isTranslating) { float3 worldPos = new float3(Mouse.Velocity.x * .0001f, Mouse.Velocity.y * -.0001f, Mouse.WheelVel * .001f); _selectedNode.GetTransform().Translation += worldPos.xyz; if (Mouse.LeftButton) { _isTranslating = false; } } //Scaling Geometry if (Keyboard.GetKey(KeyCodes.S)) { _isScaling = true; } if (_isScaling) { _selectedNode.GetTransform().Scale += new float3(Mouse.Velocity.y, Mouse.Velocity.y, Mouse.Velocity.y) * .0001f; if (Mouse.LeftButton) { _isScaling = false; } } //DeleteGeom if (Keyboard.GetKey(KeyCodes.Delete) && _keyTimeout < 0) { _keyTimeout = 1; int currentGeometryIndex = _parentNode.Children.IndexOf(_selectedNode); _activeGeometrys.Remove(currentGeometryIndex); Dictionary <int, Geometry> zwerg = new Dictionary <int, Geometry>(); foreach (int key in _activeGeometrys.Keys) { if (key > currentGeometryIndex) { Geometry test = _activeGeometrys[key]; zwerg.Add(key - 1, test); } else { zwerg.Add(key, _activeGeometrys[key]); } } _activeGeometrys.Clear(); foreach (KeyValuePair <int, Geometry> item in zwerg) { _activeGeometrys.Add(item.Key, item.Value); } _parentNode.Children.RemoveAt(currentGeometryIndex); _selectedNode = null; _currentPick = null; } //Insert if (Keyboard.GetKey(KeyCodes.I) && _keyTimeout < 0) { _keyTimeout = .25f; int currentGeometryIndex = _parentNode.Children.IndexOf(_selectedNode); SceneNode currentSelection = _parentNode.Children[currentGeometryIndex]; Geometry currentSelectedGeometry = _activeGeometrys[currentGeometryIndex]; currentSelectedGeometry.InsetFace(rng.Next(4, currentSelectedGeometry.GetAllFaces().Count()), .5f); Geometry copy = currentSelectedGeometry.CloneGeometry(); _activeGeometrys[currentGeometryIndex] = copy; currentSelectedGeometry.Triangulate(); JometriMesh geometryMesh = new JometriMesh(currentSelectedGeometry); Mesh meshComponent = new Mesh { Vertices = geometryMesh.Vertices, Triangles = geometryMesh.Triangles, Normals = geometryMesh.Normals, }; currentSelection.Components[2] = meshComponent; } //Extrude if (Keyboard.GetKey(KeyCodes.E) && _keyTimeout < 0) { _keyTimeout = .25f; int currentGeometryIndex = _parentNode.Children.IndexOf(_selectedNode); SceneNode currentSelection = _parentNode.Children[currentGeometryIndex]; Geometry currentSelectedGeometry = _activeGeometrys[currentGeometryIndex]; currentSelectedGeometry.ExtrudeFace(rng.Next(4, currentSelectedGeometry.GetAllFaces().Count()), 1); Geometry copy = currentSelectedGeometry.CloneGeometry(); _activeGeometrys[currentGeometryIndex] = copy; currentSelectedGeometry.Triangulate(); JometriMesh geometryMesh = new JometriMesh(currentSelectedGeometry); Mesh meshComponent = new Mesh { Vertices = geometryMesh.Vertices, Triangles = geometryMesh.Triangles, Normals = geometryMesh.Normals, }; currentSelection.Components[2] = meshComponent; } //Add Catmull-Clark if (Keyboard.GetKey(KeyCodes.C) && _keyTimeout < 0) { _keyTimeout = .25f; int currentGeometryIndex = _parentNode.Children.IndexOf(_selectedNode); SceneNode currentSelection = _parentNode.Children[currentGeometryIndex]; Geometry currentSelectedGeometry = _activeGeometrys[currentGeometryIndex]; currentSelectedGeometry = SubdivisionSurface.CatmullClarkSubdivision(currentSelectedGeometry); Geometry copy = currentSelectedGeometry.CloneGeometry(); _activeGeometrys[currentGeometryIndex] = copy; currentSelectedGeometry.Triangulate(); JometriMesh geometryMesh = new JometriMesh(currentSelectedGeometry); Mesh meshComponent = new Mesh { Vertices = geometryMesh.Vertices, Triangles = geometryMesh.Triangles, Normals = geometryMesh.Normals, }; currentSelection.Components[2] = meshComponent; } }
/// <summary> /// Creates and returns a UV-Sphere as a DCEL with the specified dimensions centered in the worlds coordinate system. /// </summary> /// <param name="radius">Radius of the sphere.</param> /// <param name="horizontalResolution">Lines of latitude, smallest value is 3.</param> /// <param name="verticalResolution">Lines of longitude, smallest value is 3.</param> /// <returns>A UV-Sphere centered in the world coordinate system as a DCEL.</returns> public static Geometry CreateSpehreGeometry(float radius, int horizontalResolution, int verticalResolution) { //check input if (radius <= 0) { throw new ArgumentException("Radius can not be <= 0"); } if (horizontalResolution <= 3) { horizontalResolution = 3; } if (verticalResolution <= 2) { verticalResolution = 2; } var sphere = new Geometry(); var northPole = new Vertex(sphere.CreateVertHandleId(), new float3(0, radius, 0)); var southPole = new Vertex(sphere.CreateVertHandleId(), new float3(0, -radius, 0)); var horizontalAngleStep = System.Math.PI * 2 / horizontalResolution; // s var verrticalAngleStep = System.Math.PI / verticalResolution; // t var currentLatitudeVerticesHandles = new int[horizontalResolution]; var lastLaitudeVerticesHandles = new int[horizontalResolution]; //stores last vertices to connect them later with the next latidute vertices for (var i = 1; i < verticalResolution + 1; i++) { //create all vertices if (i < verticalResolution) { for (var j = 0; j < horizontalResolution; j++) { //create all Vertices of current latitude var xPos = (float)(radius * System.Math.Sin(horizontalAngleStep * j) * System.Math.Sin(verrticalAngleStep * i)); var yPos = (float)(radius * System.Math.Cos(verrticalAngleStep * (i))); var zPos = (float)(radius * System.Math.Cos(horizontalAngleStep * j) * System.Math.Sin(verrticalAngleStep * i)); var circleVertex = new Vertex(sphere.CreateVertHandleId(), new float3(xPos, yPos, zPos)); sphere.DictVertices.Add(circleVertex.Handle, circleVertex); currentLatitudeVerticesHandles[j] = circleVertex.Handle; } } //create faces var topHeHandles = new int[horizontalResolution]; for (var j = 0; j < horizontalResolution; j++) { // bottom triangles of sphere if (i == verticalResolution) { var bottomTriangle = new Face(sphere.CreateFaceHandleId()); var h1 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); var h2 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); var h3 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); topHeHandles[j] = h1.Handle; h1.NextHalfEdge = h2.Handle; h2.NextHalfEdge = h3.Handle; h3.NextHalfEdge = h1.Handle; h1.PrevHalfEdge = h3.Handle; h2.PrevHalfEdge = h1.Handle; h3.PrevHalfEdge = h2.Handle; h1.IncidentFace = bottomTriangle.Handle; h2.IncidentFace = bottomTriangle.Handle; h3.IncidentFace = bottomTriangle.Handle; h1.OriginVertex = currentLatitudeVerticesHandles[j]; h2.OriginVertex = j == horizontalResolution - 1 ? currentLatitudeVerticesHandles[0] : currentLatitudeVerticesHandles[j + 1]; h3.OriginVertex = southPole.Handle; bottomTriangle.OuterHalfEdge = h1.Handle; southPole.IncidentHalfEdge = h3.Handle; //write changes sphere.DictHalfEdges.Add(h1.Handle, h1); sphere.DictHalfEdges.Add(h2.Handle, h2); sphere.DictHalfEdges.Add(h3.Handle, h3); sphere.DictFaces.Add(bottomTriangle.Handle, bottomTriangle); } // top triangles of sphere else if (i == 1) { var topTriangle = new Face(sphere.CreateFaceHandleId()); var h1 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); var h2 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); var h3 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); topHeHandles[j] = h1.Handle; h1.NextHalfEdge = h2.Handle; h2.NextHalfEdge = h3.Handle; h3.NextHalfEdge = h1.Handle; h1.PrevHalfEdge = h3.Handle; h2.PrevHalfEdge = h1.Handle; h3.PrevHalfEdge = h2.Handle; h1.IncidentFace = topTriangle.Handle; h2.IncidentFace = topTriangle.Handle; h3.IncidentFace = topTriangle.Handle; h1.OriginVertex = j == horizontalResolution - 1 ? currentLatitudeVerticesHandles[0] : currentLatitudeVerticesHandles[j + 1]; h2.OriginVertex = currentLatitudeVerticesHandles[j]; h3.OriginVertex = northPole.Handle; topTriangle.OuterHalfEdge = h1.Handle; var currentVertex = sphere.GetVertexByHandle(currentLatitudeVerticesHandles[j]); currentVertex.IncidentHalfEdge = h2.Handle; northPole.IncidentHalfEdge = h3.Handle; //write changes sphere.DictHalfEdges.Add(h1.Handle, h1); sphere.DictHalfEdges.Add(h2.Handle, h2); sphere.DictHalfEdges.Add(h3.Handle, h3); sphere.DictFaces.Add(topTriangle.Handle, topTriangle); sphere.ReplaceVertex(currentVertex); } // middle quads of sphere else { var quad = new Face(sphere.CreateFaceHandleId()); var h1 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); var h2 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); var h3 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); var h4 = new HalfEdge(sphere.CreateHalfEdgeHandleId()); topHeHandles[j] = h1.Handle; h1.NextHalfEdge = h2.Handle; h2.NextHalfEdge = h3.Handle; h3.NextHalfEdge = h4.Handle; h4.NextHalfEdge = h1.Handle; h1.PrevHalfEdge = h4.Handle; h2.PrevHalfEdge = h1.Handle; h3.PrevHalfEdge = h2.Handle; h4.PrevHalfEdge = h3.Handle; h1.IncidentFace = quad.Handle; h2.IncidentFace = quad.Handle; h3.IncidentFace = quad.Handle; h4.IncidentFace = quad.Handle; quad.OuterHalfEdge = h1.Handle; h4.OriginVertex = currentLatitudeVerticesHandles[j]; h3.OriginVertex = j == horizontalResolution - 1 ? currentLatitudeVerticesHandles[0] : currentLatitudeVerticesHandles[j + 1]; h2.OriginVertex = j == horizontalResolution - 1 ? lastLaitudeVerticesHandles[0] : lastLaitudeVerticesHandles[j + 1]; h1.OriginVertex = lastLaitudeVerticesHandles[j]; var currentVertex = sphere.GetVertexByHandle(currentLatitudeVerticesHandles[j]); currentVertex.IncidentHalfEdge = h4.Handle; //write changes sphere.DictFaces.Add(quad.Handle, quad); sphere.DictHalfEdges.Add(h1.Handle, h1); sphere.DictHalfEdges.Add(h2.Handle, h2); sphere.DictHalfEdges.Add(h3.Handle, h3); sphere.DictHalfEdges.Add(h4.Handle, h4); sphere.ReplaceVertex(currentVertex); } } //set twins for (int j = 0; j < horizontalResolution; j++) { //set twins of adjacent triangles bottom if (i == 1) { int nextH1Index; nextH1Index = j == 0 ? horizontalResolution - 1 : j - 1; var h1 = sphere.GetHalfEdgeByHandle(topHeHandles[j]); var h2 = sphere.GetHalfEdgeByHandle(h1.NextHalfEdge); var nextH1 = sphere.GetHalfEdgeByHandle(topHeHandles[nextH1Index]); var nextH3 = sphere.GetHalfEdgeByHandle(nextH1.PrevHalfEdge); nextH3.TwinHalfEdge = h2.Handle; h2.TwinHalfEdge = nextH3.Handle; sphere.ReplaceHalfEdge(nextH3); sphere.ReplaceHalfEdge(h2); } else if (i == verticalResolution) { int nextH1Index; nextH1Index = j == 0 ? horizontalResolution - 1 : j - 1; var h1 = sphere.GetHalfEdgeByHandle(topHeHandles[j]); var h3 = sphere.GetHalfEdgeByHandle(h1.PrevHalfEdge); var nextH1 = sphere.GetHalfEdgeByHandle(topHeHandles[nextH1Index]); var nextH2 = sphere.GetHalfEdgeByHandle(nextH1.NextHalfEdge); nextH2.TwinHalfEdge = h3.Handle; h3.TwinHalfEdge = nextH2.Handle; sphere.ReplaceHalfEdge(nextH2); sphere.ReplaceHalfEdge(h3); } else //set twins of adjacent quads { var h1 = sphere.GetHalfEdgeByHandle(topHeHandles[j]); var h4 = sphere.GetHalfEdgeByHandle(h1.PrevHalfEdge); int nextH1Index; nextH1Index = j == 0 ? horizontalResolution - 1 : j - 1; var nextH1 = sphere.GetHalfEdgeByHandle(topHeHandles[nextH1Index]); var nextH2 = sphere.GetHalfEdgeByHandle(nextH1.NextHalfEdge); nextH2.TwinHalfEdge = h4.Handle; h4.TwinHalfEdge = nextH2.Handle; sphere.ReplaceHalfEdge(nextH2); sphere.ReplaceHalfEdge(h4); } //set twin of face on top if (i > 1) { var h1 = sphere.GetHalfEdgeByHandle(topHeHandles[j]); var lastVertex = sphere.GetVertexByHandle(lastLaitudeVerticesHandles[j]); var topH1 = sphere.GetHalfEdgeByHandle(lastVertex.IncidentHalfEdge); while (true) { if (topH1.TwinHalfEdge == 0) { break; } topH1 = sphere.GetHalfEdgeByHandle(topH1.NextHalfEdge); } topH1.TwinHalfEdge = h1.Handle; h1.TwinHalfEdge = topH1.Handle; sphere.ReplaceHalfEdge(h1); sphere.ReplaceHalfEdge(topH1); } } Array.Copy(currentLatitudeVerticesHandles, lastLaitudeVerticesHandles, currentLatitudeVerticesHandles.Length); } sphere.DictVertices.Add(northPole.Handle, northPole); sphere.DictVertices.Add(southPole.Handle, southPole); //calculate normals var allFaces = sphere.GetAllFaces().ToList(); foreach (var face in allFaces) { sphere.SetFaceNormal(sphere.GetFaceVertices(face.Handle).ToList(), face); } return(sphere); }
/// <summary> /// Creates and returns a Pyramid as a DCEL with the specified dimensions centered in the worlds coordinate system. /// </summary> /// <param name="dimensionX">Width of the Pyramid in X-dimension</param> /// <param name="dimensionY">Height of the Pyramid in Y-dimension.</param> /// <param name="dimensionZ">Depth of the Pyramid in Z-dimension.</param> /// <returns></returns> public static Geometry CreatePyramidGeometry(float dimensionX, float dimensionY, float dimensionZ) { //check input if (dimensionX <= 0 || dimensionY <= 0 || dimensionZ <= 0) { throw new ArgumentException("The dimension values can not be <= 0"); } var xPos = dimensionX / 2.0f; var yPos = dimensionY / 2.0f; var zPos = dimensionZ / 2.0f; var pyramid = new Geometry(); var positions = new float3[5]; //stores all Vertices positions positions[0] = new float3(-xPos, -yPos, -zPos); positions[1] = new float3(xPos, -yPos, -zPos); positions[2] = new float3(xPos, -yPos, zPos); positions[3] = new float3(-xPos, -yPos, zPos); positions[4] = new float3(0, yPos, 0); var baseFace = new Face(6) { OuterHalfEdge = 4 }; //create nad add vertices for (var i = 0; i < 5; i++) { Vertex current = new Vertex(pyramid.CreateVertHandleId(), positions[i]); if (i < 4) { current.IncidentHalfEdge = i * 4 + 1; } if (i == 4) { current.IncidentHalfEdge = 3; } pyramid.DictVertices.Add(current.Handle, current); } //create add Edges and Faces for (var i = 0; i < 4; i++) { var h1 = new HalfEdge(i * 4 + 1); var h2 = new HalfEdge(i * 4 + 2); var h3 = new HalfEdge(i * 4 + 3); var h4 = new HalfEdge(i * 4 + 4); var sideFace = new Face(i + 2) { OuterHalfEdge = h1.Handle }; h1.IncidentFace = sideFace.Handle; h2.IncidentFace = sideFace.Handle; h3.IncidentFace = sideFace.Handle; h4.IncidentFace = baseFace.Handle; h1.NextHalfEdge = h2.Handle; h2.NextHalfEdge = h3.Handle; h3.NextHalfEdge = h1.Handle; h1.PrevHalfEdge = h3.Handle; h2.PrevHalfEdge = h1.Handle; h3.PrevHalfEdge = h2.Handle; h3.OriginVertex = pyramid.DictVertices[5].Handle; h1.TwinHalfEdge = h4.Handle; h4.TwinHalfEdge = h1.Handle; if (i < 3) { h4.PrevHalfEdge = (i + 1) * 4 + 4; h2.TwinHalfEdge = (i + 1) * 4 + 3; h1.OriginVertex = pyramid.DictVertices[i + 1].Handle; h2.OriginVertex = pyramid.DictVertices[i + 2].Handle; h4.OriginVertex = pyramid.DictVertices[i + 2].Handle; } else { h4.PrevHalfEdge = 4; h2.TwinHalfEdge = 3; h1.OriginVertex = pyramid.DictVertices[i + 1].Handle; h2.OriginVertex = pyramid.DictVertices[1].Handle; h4.OriginVertex = pyramid.DictVertices[1].Handle; } if (i > 0) { h3.TwinHalfEdge = (i - 1) * 4 + 2; h4.NextHalfEdge = (i - 1) * 4 + 4; } else { h3.TwinHalfEdge = 3 * 4 + 2; h4.NextHalfEdge = 3 * 4 + 4; } //add pyramid.DictHalfEdges.Add(h1.Handle, h1); pyramid.DictHalfEdges.Add(h2.Handle, h2); pyramid.DictHalfEdges.Add(h3.Handle, h3); pyramid.DictHalfEdges.Add(h4.Handle, h4); pyramid.DictFaces.Add(sideFace.Handle, sideFace); } pyramid.DictFaces.Add(baseFace.Handle, baseFace); pyramid.SetHighestHandles(); var allFaces = pyramid.GetAllFaces().ToList(); foreach (var face in allFaces) { var faceVertices = pyramid.GetFaceVertices(face.Handle).ToList(); pyramid.SetFaceNormal(faceVertices, face); } return(pyramid); }
/// <summary> /// Creates and returns a cone with the given dimensions. /// </summary> /// <param name="baseRadius">The radiaus of the base circle.</param> /// <param name="dimensionY">The height of the cone.</param> /// <param name="sliceCount">The horizontal resulotion of the base circle. Min value is 3. For a basic cone 15.</param> /// <returns></returns> public static Geometry CreateConeGeometry(float baseRadius, float dimensionY, int sliceCount) { //check input if (sliceCount < 3) { sliceCount = 3; } if (baseRadius <= 0 || dimensionY <= 0) { throw new ArgumentException("You can not input paramaters <= 0"); } var cone = new Geometry(); var northPole = new Vertex(cone.CreateVertHandleId(), new float3(0, dimensionY / 2, 0)); var southPole = new Vertex(cone.CreateVertHandleId(), new float3(0, -dimensionY / 2, 0)); var angleStep = System.Math.PI * 2 / sliceCount; var yPos = -dimensionY / 2.0f; int[] firstHandles = null; //stores the handles of the first slice to connect it later with the last slice var lastH3 = new HalfEdge(); var lastH2 = new HalfEdge(); var lastVertex = southPole; for (var i = 1; i < sliceCount + 1; i++) { var x = (float)System.Math.Cos(angleStep * i) * baseRadius; var z = (float)System.Math.Sin(angleStep * i) * baseRadius; var tempVertex = new Vertex(cone.CreateVertHandleId(), new float3(x, yPos, z)); //south to temp var h1 = new HalfEdge(cone.CreateHalfEdgeHandleId()); var h2 = new HalfEdge(cone.CreateHalfEdgeHandleId()); //twin of h1 tempVertex.IncidentHalfEdge = h2.Handle; h1.OriginVertex = southPole.Handle; h2.OriginVertex = tempVertex.Handle; h1.TwinHalfEdge = h2.Handle; h2.TwinHalfEdge = h1.Handle; //temp to north var h3 = new HalfEdge(cone.CreateHalfEdgeHandleId()); var h4 = new HalfEdge(cone.CreateHalfEdgeHandleId()); northPole.IncidentHalfEdge = h3.Handle; southPole.IncidentHalfEdge = h1.Handle; h3.OriginVertex = northPole.Handle; h4.OriginVertex = tempVertex.Handle; h3.TwinHalfEdge = h4.Handle; h4.TwinHalfEdge = h3.Handle; if (lastVertex == southPole) { firstHandles = new[] { tempVertex.Handle, h1.Handle, h4.Handle }; lastH3 = h3; lastH2 = h2; cone.DictVertices.Add(tempVertex.Handle, tempVertex); cone.DictHalfEdges.Add(h1.Handle, h1); cone.DictHalfEdges.Add(h2.Handle, h2); cone.DictHalfEdges.Add(h3.Handle, h3); cone.DictHalfEdges.Add(h4.Handle, h4); lastVertex = tempVertex; continue; } //temp to last var h5 = new HalfEdge(cone.CreateHalfEdgeHandleId()); var h6 = new HalfEdge(cone.CreateHalfEdgeHandleId()); h5.OriginVertex = lastVertex.Handle; h6.OriginVertex = tempVertex.Handle; h5.TwinHalfEdge = h6.Handle; h6.TwinHalfEdge = h5.Handle; //create top triangles south-temp-last var triangle1 = new Face(cone.CreateFaceHandleId()); h5.NextHalfEdge = h4.Handle; triangle1.OuterHalfEdge = h5.Handle; h4.NextHalfEdge = lastH3.Handle; lastH3.NextHalfEdge = h5.Handle; h5.IncidentFace = triangle1.Handle; h4.IncidentFace = triangle1.Handle; lastH3.IncidentFace = triangle1.Handle; h5.PrevHalfEdge = lastH3.Handle; lastH3.PrevHalfEdge = h4.Handle; h4.PrevHalfEdge = h5.Handle; //north-last-temp var triangle2 = new Face(cone.CreateFaceHandleId()); h6.NextHalfEdge = lastH2.Handle; triangle2.OuterHalfEdge = h6.Handle; lastH2.NextHalfEdge = h1.Handle; h1.NextHalfEdge = h6.Handle; h6.IncidentFace = triangle2.Handle; lastH2.IncidentFace = triangle2.Handle; h1.IncidentFace = triangle2.Handle; h6.PrevHalfEdge = h1.Handle; h1.PrevHalfEdge = lastH2.Handle; lastH2.PrevHalfEdge = h6.Handle; //write cone.DictVertices.Add(tempVertex.Handle, tempVertex); cone.DictHalfEdges.Add(h1.Handle, h1); cone.DictHalfEdges.Add(h2.Handle, h2); cone.DictHalfEdges.Add(h3.Handle, h3); cone.DictHalfEdges.Add(h4.Handle, h4); cone.DictHalfEdges.Add(h5.Handle, h5); cone.DictHalfEdges.Add(h6.Handle, h6); cone.ReplaceHalfEdge(lastH2); cone.ReplaceHalfEdge(lastH3); cone.DictFaces.Add(triangle1.Handle, triangle1); cone.DictFaces.Add(triangle2.Handle, triangle2); lastH2 = h2; lastH3 = h3; lastVertex = tempVertex; } //add south and northpole cone.DictVertices.Add(southPole.Handle, southPole); cone.DictVertices.Add(northPole.Handle, northPole); //create last 2 traingles var firstVertex = cone.GetVertexByHandle(firstHandles[0]); var firtstH1 = cone.GetHalfEdgeByHandle(firstHandles[1]); var firstH4 = cone.GetHalfEdgeByHandle(firstHandles[2]); var lastH5 = new HalfEdge(cone.CreateHalfEdgeHandleId()); var lastH6 = new HalfEdge(cone.CreateHalfEdgeHandleId()); lastH5.OriginVertex = lastVertex.Handle; lastH6.OriginVertex = firstVertex.Handle; lastH5.TwinHalfEdge = lastH6.Handle; lastH6.TwinHalfEdge = lastH5.Handle; //create to triangles south-temp-last, north-last-temp var triangleL1 = new Face(cone.CreateFaceHandleId()) { OuterHalfEdge = lastH5.Handle }; lastH5.NextHalfEdge = firstH4.Handle; firstH4.NextHalfEdge = lastH3.Handle; lastH3.NextHalfEdge = lastH5.Handle; lastH5.IncidentFace = triangleL1.Handle; firstH4.IncidentFace = triangleL1.Handle; lastH3.IncidentFace = triangleL1.Handle; lastH5.PrevHalfEdge = lastH3.Handle; lastH3.PrevHalfEdge = firstH4.Handle; firstH4.PrevHalfEdge = lastH5.Handle; var triangleL2 = new Face(cone.CreateFaceHandleId()) { OuterHalfEdge = lastH6.Handle }; lastH6.NextHalfEdge = lastH2.Handle; lastH2.NextHalfEdge = firtstH1.Handle; firtstH1.NextHalfEdge = lastH6.Handle; lastH6.IncidentFace = triangleL2.Handle; lastH2.IncidentFace = triangleL2.Handle; firtstH1.IncidentFace = triangleL2.Handle; lastH6.PrevHalfEdge = firtstH1.Handle; firtstH1.PrevHalfEdge = lastH2.Handle; lastH2.PrevHalfEdge = lastH6.Handle; //write cone.ReplaceHalfEdge(firtstH1); cone.DictHalfEdges.Add(lastH5.Handle, lastH5); cone.DictHalfEdges.Add(lastH6.Handle, lastH6); cone.ReplaceHalfEdge(lastH2); cone.ReplaceHalfEdge(lastH3); cone.ReplaceHalfEdge(firstH4); cone.DictFaces.Add(triangleL1.Handle, triangleL1); cone.DictFaces.Add(triangleL2.Handle, triangleL2); //face normals var allFaces = cone.GetAllFaces().ToList(); foreach (var face in allFaces) { cone.SetFaceNormal(cone.GetFaceVertices(face.Handle).ToList(), face); } return(cone); }