Exemple #1
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        // 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);
        }
Exemple #5
0
        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;
            }
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
Exemple #8
0
        /// <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);
        }