コード例 #1
0
ファイル: LsmBody.cs プロジェクト: stv909/TrinityEngine
        public void GenerateFromBlueprint(bool[,] blueprint)
        {
            this.blueprint = blueprint;

            width = blueprint.GetLength(0);
            height = blueprint.GetLength(1);

            lattice = new LatticePoint[width, height];

            int x, y;

            for (x = 0; x < width; x++)
            {
                for (y = 0; y < height; y++)
                {
                    lattice[x, y] = new LatticePoint();
                    lattice[x,y].index = new Point(x,y);

                    if (blueprint[x, y] == true)
                    {
                        // Generate particle
                        Particle p = new Particle();
                        lattice[x, y].particle = p;
                        p.body = this;
                        p.x0 = new Vector2(spacing.X * x, spacing.Y * y);
                        p.x = offset + p.x0;
                        p.latticePoint = lattice[x, y];
                        p.goal = p.x;
                        particles.Add(p);
                    }
                    else
                    {
                    }
                }
            }

            // Set up the neighbors
            for (x = 0; x < width; x++)
            {
                for (y = 0; y < height; y++)
                {
                    if (blueprint[x, y] == true)
                    {
                        if (InBounds(x + 1, y) && blueprint[x + 1, y] == true)
                        {
                            lattice[x, y].particle.xPos = lattice[x + 1, y].particle;
                            lattice[x + 1, y].particle.xNeg = lattice[x, y].particle;
                        }
                        if (InBounds(x, y + 1) && blueprint[x, y + 1] == true)
                        {
                            lattice[x, y].particle.yPos = lattice[x, y + 1].particle;
                            lattice[x, y + 1].particle.yNeg = lattice[x, y].particle;
                        }
                    }
                }
            }

            // Create the smoothing regions and have them generate themselves
            foreach (Particle p in particles)
            {
                SmoothingRegion s = new SmoothingRegion(w);
                s.body = this;
                s.latticePoint = p.latticePoint;
                s.latticePoint.smoothingRegion = s;
                s.RegenerateRegion();
                smoothingRegions.Add(s);
            }

            // Create one chunk with all the particles in it
            Chunk c = new Chunk();
            foreach (Particle p in particles)
            {
                c.particles.Add(p);
                p.chunk = c;
            }
            c.CalculateInvariants();
            chunks.Add(c);

            // Setup the regions
            foreach (SmoothingRegion s in smoothingRegions)
            {
                s.CalculateInvariants();
            }
        }
コード例 #2
0
ファイル: Particle.cs プロジェクト: stv909/TrinityEngine
        public bool DoFracture(ref Particle other, ref Particle me)
        {
            bool somethingBroke = false;

            double len = (other.goal - goal).Length();
            double rest = (other.x0 - x0).Length();
            double off = Math.Abs((len / rest) - 1.0);
            if (off > LsmBody.fractureLengthTolerance)
            {
                somethingBroke = true;
                Testbed.PostMessage("Length fracture: Rest = " + rest + ", actual = " + len);
            }

            if (!somethingBroke)
            {
                Vector2 a = new Vector2(other.R[0, 0], other.R[1, 0]);
                Vector2 b = new Vector2(R[0, 0], R[1, 0]);
                a.Normalize();
                b.Normalize();
                double angleDifference = Math.Acos(a.Dot(b));
                if (angleDifference > LsmBody.fractureAngleTolerance)
                {
                    somethingBroke = true;
                    Testbed.PostMessage("Angle fracture: angle difference = " + angleDifference);
                }
            }

            if (somethingBroke)
            {
                Particle saved = other;
                me = null;
                other = null;

                // Check if the chunks are still connected
                Queue<Particle> edge = new Queue<Particle>();
                List<Particle> found = new List<Particle>();
                edge.Enqueue(this);
                bool connected = false;
                while (edge.Count > 0)
                {
                    Particle p = edge.Dequeue();
                    if (!found.Contains(p))
                    {
                        found.Add(p);
                        if (p == saved)
                        {
                            // Connected
                            connected = true;
                            break;
                        }
                        if (p.xPos != null)
                            edge.Enqueue(p.xPos);
                        if (p.xNeg != null)
                            edge.Enqueue(p.xNeg);
                        if (p.yPos != null)
                            edge.Enqueue(p.yPos);
                        if (p.yNeg != null)
                            edge.Enqueue(p.yNeg);
                    }
                }
                if (connected == false)
                {
                    // The chunks broke - there are now two separate chunks (maximally connected subgraphs)
                    chunk.particles.Clear();
                    chunk.particles.AddRange(found);
                    chunk.CalculateInvariants();

                    Chunk newChunk = new Chunk();

                    edge.Clear();
                    found.Clear();
                    edge.Enqueue(saved);
                    while (edge.Count > 0)
                    {
                        Particle p = edge.Dequeue();
                        if (!found.Contains(p))
                        {
                            found.Add(p);
                            p.chunk = newChunk;
                            if (p.xPos != null)
                                edge.Enqueue(p.xPos);
                            if (p.xNeg != null)
                                edge.Enqueue(p.xNeg);
                            if (p.yPos != null)
                                edge.Enqueue(p.yPos);
                            if (p.yNeg != null)
                                edge.Enqueue(p.yNeg);
                        }
                    }

                    newChunk.particles.AddRange(found);
                    newChunk.CalculateInvariants();
                    body.chunks.Add(newChunk);

                    Testbed.PostMessage("Chunk broken: the original chunk now has " + chunk.particles.Count + " particles, the new chunk has " + newChunk.particles.Count + " particles.");
                    Testbed.PostMessage("Number of chunks / particles: " + body.chunks.Count + " / " + body.particles.Count);
                }
            }

            return somethingBroke;
        }