Пример #1
0
        private void ProcessPart(RenderMeshPart part, List <int> startPoints, List <float> distance, bool isMirrored = false)
        {
            if (shapedParts.ContainsKey(part.Guid))
            {
                return;
            }
            shapedParts.Add(part.Guid, part);
            var nextParts = new Dictionary <Guid, ShapePartInfo>();

            for (var i = 0; i < startPoints.Count; i++)
            {
                var index = startPoints[i];
                var p     = part.Points[index];
                if (!shapePoints.ContainsKey(p.Position))
                {
                    shapePoints.Add(p.Position, new ShapePointData());
                }
                var sp = shapePoints[p.Position];
                sp.PartsPoints.Add(new KeyValuePair <RenderMeshPart, int>(part, index));
                sp.Distance   = Math.Min(sp.Distance, distance[i]);
                sp.IsMirrored = isMirrored;
            }
            for (var i = 0; i < startPoints.Count; i++)
            {
                ProcessPoint(part, startPoints[i], distance[i], ref nextParts, isMirrored);
            }
            foreach (var pt in nextParts)
            {
                var p = headMeshController.RenderMesh.Parts.First(r => r.Guid.Equals(pt.Key));
                ProcessPart(p, pt.Value.Points, pt.Value.Distance, isMirrored);
            }
        }
Пример #2
0
        public static RenderMeshPart FromStream(BinaryReader br)
        {
            var result = new RenderMeshPart();

            result.Guid = new Guid(br.ReadString());
            result.Name = br.ReadString();

            var cnt = br.ReadInt32();

            result.CountIndices = cnt;
            for (var i = 0; i < cnt; i++)
            {
                result.Indices.Add(br.ReadUInt32());
            }

            cnt = br.ReadInt32();
            if (cnt != 0)
            {
                result.Vertices = new Vertex3d[cnt];
                for (var i = 0; i < cnt; i++)
                {
                    result.Vertices[i] = Vertex3d.FromStream(br);
                }
            }

            cnt = br.ReadInt32();
            for (var i = 0; i < cnt; i++)
            {
                result.Points.Add(Point3d.FromStream(br));
            }

            result.TextureName            = br.ReadString();
            result.TransparentTextureName = br.ReadString();

            result.Color         = Vector4Ex.FromStream(br);
            result.Type          = (HeadMeshType)br.ReadInt32();
            result.IsBaseTexture = br.ReadBoolean();

            result.Destroy();
            GL.GenBuffers(1, out result.VertexBuffer);
            GL.GenBuffers(1, out result.IndexBuffer);

            return(result);
        }
Пример #3
0
        public float StartShaping(Vector3 point, Matrix4 vm, bool isMirror, float radius, ShapeCoefType type)
        {
            EndShape();
            var depth = -10000.0f;

            foreach (var part in headMeshController.RenderMesh.Parts)
            {
                for (var i = 0; i < part.Indices.Count; i += 3)
                {
                    var p0 = Vector3.Transform(part.Vertices[part.Indices[i]].Position, vm);
                    var p1 = Vector3.Transform(part.Vertices[part.Indices[i + 1]].Position, vm);
                    var p2 = Vector3.Transform(part.Vertices[part.Indices[i + 2]].Position, vm);

                    var a = p0.Xy;
                    var b = p1.Xy;
                    var c = p2.Xy;

                    if (TexturingInfo.PointInTriangle(ref a, ref b, ref c, ref point))
                    {
                        var aup = a.X - point.X;
                        var bup = b.X - point.X;
                        var cup = c.X - point.X;
                        var avp = a.Y - point.Y;
                        var bvp = b.Y - point.Y;
                        var cvp = c.Y - point.Y;

                        var f = 1.0f / ((b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X));
                        var u = (bup * cvp - bvp * cup) * f;
                        var v = (cup * avp - cvp * aup) * f;
                        var w = 1.0f - (u + v);

                        var z = u * p0.Z + v * p1.Z + w * p2.Z;
                        if (depth < z)
                        {
                            startPart     = part;
                            startTriangle = i;
                            depth         = z;
                        }
                    }
                }
            }

            if (startPart == null || startTriangle < 0)
            {
                return(0.0f);
            }

            ShapePoint          = point;
            ShapePoint.Z        = depth;
            ShapePoint          = Vector3.Transform(ShapePoint, vm.Inverted());
            startTriangleMirror = -1;
            if (isMirror)
            {
                //Ищем точку в оригинальных координатах
                var triangle = new[] { startPart.Indices[startTriangle], startPart.Indices[startTriangle + 1], startPart.Indices[startTriangle + 2] };
                var a        = startPart.Vertices[triangle[0]].OriginalPosition;
                var b        = startPart.Vertices[triangle[1]].OriginalPosition;
                var c        = startPart.Vertices[triangle[2]].OriginalPosition;
                a.X   *= -1.0f;
                b.X   *= -1.0f;
                c.X   *= -1.0f;
                isLeft = ShapePoint.X < 0.0f ? 1.0f : -1.0f;
                int idA = -1, idB = -1, idC = -1;
                for (int i = 0; i < startPart.Vertices.Length; i++)
                {
                    if (idA >= 0 && idB >= 0 && idC >= 0)
                    {
                        break;
                    }
                    var position = startPart.Vertices[i].OriginalPosition;
                    if (position.X * isLeft >= 0.0f)
                    {
                        if (idA < 0 && VectorEqualityComparer.EqualsVector3(position, a))
                        {
                            idA = i;
                            continue;
                        }
                        if (idB < 0 && VectorEqualityComparer.EqualsVector3(position, b))
                        {
                            idB = i;
                            continue;
                        }
                        if (idC < 0 && VectorEqualityComparer.EqualsVector3(position, c))
                        {
                            idC = i;
                            continue;
                        }
                    }
                }
                if (idA >= 0 && idB >= 0 && idC >= 0)
                {
                    for (int i = 0; i < startPart.Indices.Count; i += 3)
                    {
                        var v0 = startPart.Indices[i];
                        var v1 = startPart.Indices[i + 1];
                        var v2 = startPart.Indices[i + 2];
                        if ((v0 == idA || v0 == idB || v0 == idC) && (v1 == idA || v1 == idB || v1 == idC) && (v2 == idA || v2 == idB || v2 == idC))
                        {
                            startTriangleMirror = i;
                            break;
                        }
                    }
                }
            }
            if (!UpdateRadius(radius))
            {
                return(0.0f);
            }
            UpdateCoef(type, radius);
            return(depth);
        }
Пример #4
0
        private void ProcessPoint(RenderMeshPart part, int p, float distance, ref Dictionary <Guid, ShapePartInfo> nextParts, bool isMirrored = false)
        {
            var point   = part.Points[p];
            var nearest = new Dictionary <int, float>();

            foreach (var n in point.Nearests)
            {
                var pos = part.Points[n].Position;
                if (isMirrored && pos.X * isLeft < 0.0f)
                {
                    continue;
                }
                var dist = (pos - point.Position).Length + distance;
                nearest.Add(n, dist);
            }

            //Берем все точки в радиусе заданном
            var where = nearest.Where(r => r.Value < shapeRadius).ToList();
            foreach (var n in where)
            {
                //оставляем только те у которых уменьшилась дистанция
                var pt = part.Points[n.Key];
                if (shapePoints.ContainsKey(pt.Position))
                {
                    var sp = shapePoints[pt.Position];
                    if (sp.PartsPoints.FindIndex(r => r.Value.Equals(n.Key) && r.Key.Guid.Equals(part.Guid)) < 0)
                    {
                        sp.PartsPoints.Add(new KeyValuePair <RenderMeshPart, int>(part, n.Key));
                    }
                    else
                    {
                        if (sp.Distance <= n.Value)
                        {
                            nearest[n.Key] = 10000.0f;
                        }
                    }
                    sp.Distance   = Math.Min(sp.Distance, n.Value);
                    sp.IsMirrored = isMirrored;
                }
                //или новые точки
                else
                {
                    var sp = new ShapePointData();
                    sp.Distance   = n.Value;
                    sp.IsMirrored = isMirrored;
                    sp.PartsPoints.Add(new KeyValuePair <RenderMeshPart, int>(part, n.Key));
                    shapePoints.Add(pt.Position, sp);
                }
            }

            foreach (var n in nearest.Where(r => r.Value < shapeRadius))
            {
                var np = part.Points[n.Key];
                foreach (var prt in headMeshController.RenderMesh.Parts.Where(r => r.Guid != part.Guid))
                {
                    int id = -1;

                    if (prt.PointsIndices.TryGetValue(np, out id))
                    {
                        if (nextParts.ContainsKey(prt.Guid))
                        {
                            var nextPart = nextParts[prt.Guid];
                            if (!nextPart.Points.Contains(id))
                            {
                                nextPart.Points.Add(id);
                                nextPart.Distance.Add(n.Value);
                            }
                            else
                            {
                                var i = nextPart.Points.IndexOf(id);
                                nextPart.Distance[i] = Math.Min(nextPart.Distance[i], n.Value);
                            }
                        }
                        else
                        {
                            nextParts.Add(prt.Guid, new ShapePartInfo {
                                Distance = new List <float> {
                                    n.Value
                                },
                                Points = new List <int> {
                                    id
                                }
                            });
                        }
                    }
                }
            }
            foreach (var n in nearest.Where(r => r.Value < shapeRadius))
            {
                ProcessPoint(part, n.Key, n.Value, ref nextParts, isMirrored);
            }
        }
Пример #5
0
 public void EndShape()
 {
     ClearSelection();
     startPart     = null;
     startTriangle = -1;
 }