Exemplo n.º 1
0
        private void BevelFace(SolidFace solidFace, int num)
        {
            var face  = solidFace.Face;
            var solid = solidFace.Solid.Copy;

            // Remember the original positions
            var vertexPositions = face.Vertices.Select(x => x.Position).ToList();

            // Scale the face a bit and move it away by the bevel distance
            var origin = face.Origin;

            face.Transform(Matrix4x4.CreateScale(Vector3.One * 0.9f, origin));
            face.Transform(Matrix4x4.CreateTranslation(face.Plane.Normal * num));

            var vertList = face.Vertices.ToList();

            // Create a face for each new edge -> old edge
            foreach (var edge in face.GetEdges())
            {
                var startIndex = vertList.FindIndex(x => x.Position.EquivalentTo(edge.Start));
                var endIndex   = vertList.FindIndex(x => x.Position.EquivalentTo(edge.End));
                var verts      = new[] { vertexPositions[startIndex], vertexPositions[endIndex], edge.End, edge.Start };
                var f          = new MutableFace(verts, face.Texture.Clone());
                solid.Faces.Add(f);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Checks if a ray is colliding with a solid by checking against it planes
        /// Uses ray vs convex polyheron algorithm
        /// We can do this because the solid brushes are always convex!!!
        /// Else we had to use a check against polygon also
        /// </summary>
        /// <param name="solid"></param>
        /// <param name="hitFace"></param>
        /// <param name="tRef"></param>
        /// <returns></returns>
        public bool IsIntersecting(Solid solid, ref SolidFace hitFace,
                                   ref float tRef)
        {
            float   tfirst    = 0.0f;
            float   tlast     = float.MaxValue;
            Vector3 origin    = Origin;
            Vector3 direction = Direction;

            foreach (SolidFace face in solid.Faces)
            {
                if (face.Indices.Count < 3)
                {
                    continue;
                }

                int     index        = face.Indices[0].Index;
                Vector3 pointOnPlane = solid.VertexPositions[index];

                float distanceToPlane = Vector3.Dot(face.Normal, origin - pointOnPlane);
                float denom           = Vector3.Dot(direction, face.Normal);

                if (Math.Abs(denom) < GeneralUtility.Epsilon)
                {
                    if (distanceToPlane > 0.0f)
                    {
                        return(false);
                    }
                }
                else
                {
                    float t = -distanceToPlane / denom;
                    if (denom < -GeneralUtility.Epsilon)
                    {
                        if (t > tfirst)
                        {
                            tfirst  = t;
                            hitFace = face;
                        }
                    }
                    else
                    {
                        if (t < tlast)
                        {
                            tlast = t;
                        }
                    }

                    if (tfirst > tlast)
                    {
                        return(false);
                    }
                }
            }

            tRef = tfirst;
            return(true);
        }
Exemplo n.º 3
0
        public SolidFace CreateFace(params int[] indices)
        {
            SolidFace face = new SolidFace();

            // save as trianglefan
            foreach (int index in indices)
            {
                face.Indices.Add(CreateIndex(index));
            }

            return(face);
        }
Exemplo n.º 4
0
        public override bool OnMouseDown(Point mouseCurPos, MouseButtons button, BaseViewport viewport)
        {
            MapObjectGroup selectedMapObjectGroup = controller.Selection;
            MapObject      rootMapObject          = controller.GetMapObjectIfHit(mouseCurPos.X, mouseCurPos.Y, viewport);

            if (viewport.ViewportType == BaseViewport.ViewportTypes.PERSPECTIVE)
            {
                if (rootMapObject == null)
                {
                    SetAllFacesSelected(false);
                    selectedMapObjectGroup.Clear();
                }
                else
                {
                    SolidFaceHitOperation operation = new SolidFaceHitOperation(viewport, mouseCurPos);
                    rootMapObject.PerformOperation(operation);

                    SolidFace hitFace = operation.hitFace;
                    if (modifierKey == Keys.Control)
                    {
                        if (!AreAnyFacesSelected(rootMapObject))
                        {
                            controller.Selection.Add(rootMapObject);
                        }

                        hitFace.Selected = !hitFace.Selected;

                        if (!AreAnyFacesSelected(rootMapObject))
                        {
                            controller.Selection.Remove(rootMapObject);
                        }
                    }
                    else if (!hitFace.Selected)
                    {
                        SetAllFacesSelected(false);
                        selectedMapObjectGroup.Clear();

                        hitFace.Selected = true;
                        selectedMapObjectGroup.Add(rootMapObject);
                    }
                }
            }
            else if (rootMapObject == null) // deselect faces when pressing in empty ortho viewport space
            {
                SetAllFacesSelected(false);
                controller.Selection.Clear();
            }

            controller.UpdateUserInterface();

            return(true);
        }
Exemplo n.º 5
0
        public void Visit(Solid solid)
        {
            float     tFraction = float.MaxValue;
            SolidFace face      = null;

            if (ray.IsIntersecting(solid, ref face, ref tFraction))
            {
                if (tFraction < t)
                {
                    t       = tFraction;
                    hitFace = face;
                }
            }
        }
Exemplo n.º 6
0
        private void CheckIntersection(Solid solid, ref float tFraction)
        {
            SolidFace hitFace = null;

            if (viewport.ViewportType != BaseViewport.ViewportTypes.PERSPECTIVE)
            {
                hasIntersected = CheckBrushCenterHit(solid, ref tFraction) ||
                                 CheckBrushEdgesHit(solid, ref tFraction);
            }
            else
            {
                hasIntersected = ray.IsIntersecting(solid, ref hitFace, ref tFraction);
            }
        }
Exemplo n.º 7
0
        private List <SolidFace> ExtractFaces(JProperty property)
        {
            if (property.Type != JTokenType.Property || !property.HasValues)
            {
                return(null);
            }

            JArray faceArray = property.Value as JArray;

            if (faceArray == null)
            {
                return(null);
            }

            List <SolidFace> faces = new List <SolidFace>();

            foreach (JObject faceObject in faceArray.Children <JObject>())
            {
                SolidFace face = new SolidFace();
                foreach (JProperty data in faceObject.Children <JProperty>())
                {
                    switch (data.Name)
                    {
                    case "texture":
                        Texture2D texture = new Texture2D(data.Value.ToString(), false);
                        face.Texture = texture;
                        break;

                    case "texturemapping":
                        face.TextureMapping = ExtractTexturemapping(data.Value <JProperty>());
                        break;

                    case "indices":
                        List <SolidIndex> indices = ExtractIndices(data.Value.Value <JArray>());
                        face.Indices.AddRange(indices);
                        break;
                    }
                }

                faces.Add(face);
            }

            if (faces.Count <= 0)
            {
                throw new RunegearFileformatErrorException("Some solid faces could not be added!");
            }

            return(faces);
        }
Exemplo n.º 8
0
        private void PokeFace(SolidFace solidFace, int num)
        {
            var face  = solidFace.Face;
            var solid = solidFace.Solid.Copy;

            // Remove the face
            solid.Faces.Remove(face);

            var center = face.Origin + face.Plane.Normal * num;

            foreach (var edge in face.GetEdges())
            {
                var v1    = face.Vertices.First(x => x.Position.EquivalentTo(edge.Start));
                var v2    = face.Vertices.First(x => x.Position.EquivalentTo(edge.End));
                var verts = new[] { v1.Position, v2.Position, center };
                var f     = new MutableFace(verts, face.Texture.Clone());
                solid.Faces.Add(f);
            }
        }
Exemplo n.º 9
0
        public override Solid CreateSolid(AABB bounds)
        {
            int       piePieces  = sidesPropertyControl.Sides;
            Solid     solidCone  = new Solid();
            SolidFace bottomFace = new SolidFace();

            // create 4 corners points for the box
            float halfWidth  = (bounds.Max.X - bounds.Min.X) / 2.0f;
            float halfHeight = (bounds.Max.Y - bounds.Min.Y) / 2.0f;
            float halfDepth  = (bounds.Max.Z - bounds.Min.Z) / 2.0f;

            solidCone.Bounds = (AABB)bounds.Clone();
            solidCone.VertexPositions.Add(new Vector3(bounds.Center.X, bounds.Center.Y, -halfDepth));

            float degToRad = (float)(Math.PI / 180.0);
            float radPiece = (360.0f / piePieces * degToRad);

            // create vertices
            for (int i = 0; i < piePieces; i++)
            {
                SolidIndex index    = new SolidIndex();
                Vector3    position = new Vector3
                {
                    X = (float)Math.Cos(i * -radPiece) * halfWidth,
                    Y = (float)Math.Sin(i * -radPiece) * halfHeight,
                    Z = halfDepth
                };
                index.Index = i + 1;

                solidCone.VertexPositions.Add(bounds.Center + position);
                bottomFace.Indices.Add(index);
            }

            solidCone.Faces.Add(bottomFace);
            int vertexCount = solidCone.VertexPositions.Count;

            // generate body
            for (int i = 0; i < piePieces; i++)
            {
                int index     = i + 1;
                int nextIndex = index + 1;
                if (nextIndex == vertexCount)
                {
                    nextIndex = 1;
                }

                SolidFace bodyFace = new SolidFace();

                SolidIndex a = new SolidIndex {
                    Index = 0
                };
                SolidIndex b = new SolidIndex {
                    Index = index
                };
                SolidIndex c = new SolidIndex {
                    Index = nextIndex
                };

                bodyFace.Indices.Add(c);
                bodyFace.Indices.Add(b);
                bodyFace.Indices.Add(a);

                solidCone.Faces.Add(bodyFace);
            }

            return(solidCone);
        }
Exemplo n.º 10
0
        public override Solid CreateSolid(AABB bounds)
        {
            int       piePieces     = sidesPropertyControl.Sides;
            Solid     solidCylinder = new Solid();
            SolidFace topFace       = new SolidFace();
            SolidFace bottomFace    = new SolidFace();

            solidCylinder.Bounds = (AABB)bounds.Clone();
            Vector3 center = bounds.Center;

            // create 4 corners points for the box
            float halfWidth  = (bounds.Max.X - bounds.Min.X) / 2.0f;
            float halfHeight = (bounds.Max.Y - bounds.Min.Y) / 2.0f;
            float halfDepth  = (bounds.Max.Z - bounds.Min.Z) / 2.0f;

            float degToRad = (float)(Math.PI / 180.0);
            float radPiece = (360.0f / piePieces * degToRad);

            // create top and bottom face
            for (int i = 0; i < piePieces; i++)
            {
                SolidIndex topIndex    = new SolidIndex();
                SolidIndex bottomIndex = new SolidIndex();
                Vector3    position    = new Vector3
                {
                    X = (float)Math.Cos(i * radPiece) * halfWidth,
                    Y = (float)Math.Sin(i * radPiece) * halfHeight
                };

                solidCylinder.VertexPositions.Add(center + new Vector3(position.X, position.Y, -halfDepth));
                solidCylinder.VertexPositions.Add(center + new Vector3(position.X, position.Y, halfDepth));

                topIndex.Index    = i * 2;
                bottomIndex.Index = piePieces * 2 - (i * 2 + 1);

                topFace.Indices.Add(topIndex);
                bottomFace.Indices.Add(bottomIndex);
            }

            solidCylinder.Faces.Add(topFace);
            solidCylinder.Faces.Add(bottomFace);

            // generate body
            for (int i = 0; i < piePieces; i++)
            {
                int nextIndex = i + 1;
                if (nextIndex == piePieces)
                {
                    nextIndex = 0;
                }

                SolidFace  bodyFace = new SolidFace();
                SolidIndex a        = new SolidIndex();
                SolidIndex b        = new SolidIndex();
                SolidIndex c        = new SolidIndex();
                SolidIndex d        = new SolidIndex();

                a.Index = i * 2;
                b.Index = i * 2 + 1;
                c.Index = nextIndex * 2 + 1;
                d.Index = nextIndex * 2;

                bodyFace.Indices.Add(a);
                bodyFace.Indices.Add(b);
                bodyFace.Indices.Add(c);
                bodyFace.Indices.Add(d);

                solidCylinder.Faces.Add(bodyFace);
            }

            return(solidCylinder);
        }