TrailCrossing TrailCrossingFor(Puff p1, Puff q1)
    {
        TrailCrossing trailCrossing = null;

        // Check if a trail crossing already exists for this segment crossing
        if (segmentCrossings.ContainsKey(p1.Index - 1))
        {
            if (Math.Abs(segmentCrossings[p1.Index - 1].Index2 - q1.Index) <= 1)
            {
                trailCrossing = segmentCrossings[p1.Index - 1].TrailCrossing;
            }
        }
        if (segmentCrossings.ContainsKey(q1.Index - 1))
        {
            if (Math.Abs(segmentCrossings[q1.Index - 1].Index1 - p1.Index) <= 1)
            {
                if (trailCrossing != null)
                {
                    Debug.Assert(segmentCrossings[q1.Index - 1].TrailCrossing == trailCrossing);
                }
                else
                {
                    trailCrossing = segmentCrossings[q1.Index - 1].TrailCrossing;
                }
            }
        }

        if (trailCrossing == null)
        {
            trailCrossing = new TrailCrossing(++crossingCount);
            trailCrossings.Add(trailCrossing);
        }

        return(trailCrossing);
    }
Esempio n. 2
0
        public void LoadContent(World world)
        {
            m_Direction = new Vector2(0, 0);
            foreach (string s in m_BlinkingTextures)
            {
                TextureBank.GetTexture(s);
            }
            m_Texture = TextureBank.GetTexture(m_BlinkingTextures[0]);

            Width  = m_Texture != null ? m_Texture.Width : 0;
            Height = m_Texture != null ? m_Texture.Height : 0;

            if (m_Texture != null)
            {
                m_Bounds.Width  = Width;
                m_Bounds.Height = Height;
                m_Bounds.X      = (int)Position.X - Width / 2;
                m_Bounds.Y      = (int)Position.Y - Height / 2;
                m_Origin.X      = Width / 2;
                m_Origin.Y      = Height / 2;
            }

            _circleBody               = BodyFactory.CreateCircle(world, ConvertUnits.ToSimUnits(35 / 2f), 1f, ConvertUnits.ToSimUnits(Position));
            _circleBody.BodyType      = BodyType.Dynamic;
            _circleBody.Mass          = 5f;
            _circleBody.LinearDamping = 3f;
            _circleBody.Restitution   = .5f;

            circleCenter    = Position;
            circleCenter.Y += circleRadius;

            puffExplosion = new Puff();
        }
Esempio n. 3
0
    public void shootPuff()
    {
        float rot  = transform.rotation.y;
        Puff  newP = Instantiate(p, new Vector3(transform.position.x - 0.3f, transform.position.y - 0.35f), transform.rotation);

        newP.SetDirection(rot == 0);
        newP.tag = tag;
    }
Esempio n. 4
0
    void Awake()
    {
        // Register the singleton
        if (Instance != null)
        {
            Debug.LogError("Multiple instances of Puff!");
        }

        Instance = this;
    }
    void ConnectPuffs(Puff p1, Puff p2, bool overlaps)
    {
        GameObject prefab        = overlaps ? overlappingLinkPrefab : linkPrefab;
        GameObject newPuffObject = Instantiate(prefab, p1.Position, Quaternion.identity);

        float dist = Vector3.Distance(p1.Position, p2.Position);

        newPuffObject.transform.localScale = new Vector3(1, 1, dist);

        Quaternion rotation = Quaternion.LookRotation(p2.Position - p1.Position);

        newPuffObject.transform.rotation = rotation;
    }
    IEnumerator DrawTrail(TrailManager trailManager)
    {
        Puff prevPuff = null;

        foreach (Puff puff in trailManager)
        {
            if (prevPuff != null)
            {
                bool drawSegment = true;
                if (segmentCrossings.ContainsKey(prevPuff.Index))
                {
                    var segmentCrossing = segmentCrossings[prevPuff.Index];

                    if (segmentCrossing.IsUnder(prevPuff.Index))
                    {
                        drawSegment = false;
                    }

                    if (actualText != null)
                    {
                        int maxCrossingNumber = segmentCrossing.IsFirst(prevPuff.Index)
                            ? segmentCrossing.TrailCrossing.CrossingNumber1
                            : segmentCrossing.TrailCrossing.CrossingNumber2;
                        actualText.text = ActualCrossingString(maxCrossingNumber);
                    }
                }

                bool overlapping = overlaps.Contains(prevPuff.Index);

                if (drawSegment)
                {
                    ConnectPuffs(prevPuff, puff, overlapping);
                }

                if (overlapping && actualText != null)
                {
                    actualText.color = Color.red;
                }

                yield return(new WaitForSeconds(0.05f));
            }
            prevPuff = puff;
        }
    }
    void RegisterCrossing(Puff p1, Puff p2, Puff q1, Puff q2, IntersectionResult result)
    {
        Debug.Log("Crossing between " + p1.Index + " and " + q1.Index);

        var trailCrossing = TrailCrossingFor(p1, q1);

        if (trailCrossing.Height == CrossingHeight.Unknown)
        {
            trailCrossing.Height = ClassifyCrossingHeight(
                p1.Position, p2.Position, q1.Position, q2.Position
                );
        }
        if (trailCrossing.Direction == CrossingDirection.Unknown)
        {
            trailCrossing.Direction = (result == IntersectionResult.IntersectingFromRight)
                ? CrossingDirection.Right
                : CrossingDirection.Left;
        }

        var crossing = new SegmentCrossing(p1.Index, q1.Index, trailCrossing);

        RegisterSegmentCrossing(p1.Index, crossing);
        RegisterSegmentCrossing(q1.Index, crossing);
    }
    void IdentifyCrossings(TrailManager trailManager)
    {
        float dist = trailManager.MinPuffDistance * 1.5f;

        Puff    p0     = null;
        Vector2 pos_p0 = Vector2.zero; // To silence compiler warning

        foreach (Puff p1 in trailManager)
        {
            Vector2 pos_p1 = new Vector2(p1.Position.x, p1.Position.z);

            // Check if this segment is part of an already identified crossing. If so, then
            // update its crossing number. This can be done now that the number of crossings up
            // till now is known. Note, we still should check for other crossings to signal
            // possible (undesired) overlaps.
            if (segmentCrossings.ContainsKey(p1.Index))
            {
                var trailCrossing = segmentCrossings[p1.Index].TrailCrossing;
                if (trailCrossing.CrossingNumber2 < 0)
                {
                    trailCrossing.CrossingNumber2 = ++crossingCount;
                }
            }

            if (p0 != null)
            {
                Vector2 midP = (pos_p0 + pos_p1) / 2;

                Puff    q0     = null;
                Vector2 pos_q0 = Vector2.zero; // To silence compiler warning

                var nearbyEnum = trailManager.GetNearbyPuffs(midP, dist, p1.Index + 1);
                while (nearbyEnum.MoveNext())
                {
                    Puff    q1     = nearbyEnum.Current;
                    Vector2 pos_q1 = new Vector2(q1.Position.x, q1.Position.z);
                    if (q0 != null && q0.Index + 1 == q1.Index)
                    {
                        IntersectionResult result = MathUtil.DoLineSegmentsIntersect(
                            pos_p0, pos_p1, pos_q0, pos_q1
                            );
                        if (result != IntersectionResult.NotTouching)
                        {
                            if (result == IntersectionResult.Overlapping)
                            {
                                RegisterOverlap(p0.Index, q0.Index);
                            }
                            else
                            {
                                RegisterCrossing(p0, p1, q0, q1, result);
                            }
                        }
                    }
                    q0     = q1;
                    pos_q0 = pos_q1;
                }
            }
            p0     = p1;
            pos_p0 = pos_p1;
        }
    }
Esempio n. 9
0
        public unsafe PngImage(byte[] fileData, int byteOffset = 0)
        {
            fixed (byte* pFileData = fileData)
            {
                byte* p = pFileData + byteOffset;
                int remaining = fileData.Length - byteOffset;

                // Signature
                if (remaining < 8)
                    throw new InvalidDataException("The file data ends abruptly");
                remaining -= 8;

                if (*(ulong*)p != Helper.PngSignature)
                    throw new InvalidDataException("PNG signature is missing or incorect");
                p += 8;

                // IHDR
                if (remaining < Header.StructLength)
                    throw new InvalidDataException("The file data ends abruptly");
                remaining -= Header.StructLength;

                var pHeader = (Header*) p;
                p += Header.StructLength;

                if (pHeader->ChunkType.Value != Helper.IHDR)
                    throw new InvalidDataException(string.Format("IHDR chunk expected, but {0} found.", pHeader->ChunkType.ToString()));
                if (pHeader->LengthFlipped.FlipEndianness() != Header.DataLength)
                    throw new InvalidDataException("IHDR length must be exactly 13 bytes");

                Width = (int)pHeader->WidthFlipped.FlipEndianness();
                Height = (int)pHeader->HeightFlipped.FlipEndianness();
                BitDepth = pHeader->BitDepth;
                ColorType = pHeader->ColorType;
                CompressionMethod = pHeader->CompressionMethod;
                FilterMethod = pHeader->FilterMethod;
                InterlaceMethod = pHeader->InterlaceMethod;

                bool endFound = false;
                List<PointerLengthPair> compressedDataParts = null;
                int totalCompressedDataLength = 0;
                bool idatFinished = false;

                while (!endFound)
                {
                    if (remaining < ChunkBeginning.StructLength)
                        throw new InvalidDataException("The file data ends abruptly");
                    remaining -= ChunkBeginning.StructLength;

                    var pChunkBeginning = (ChunkBeginning*) p;
                    p += ChunkBeginning.StructLength;

                    int length = (int)pChunkBeginning->LengthFlipped.FlipEndianness();

                    if (remaining < length + 4)
                        throw new InvalidDataException("The file data ends abruptly");
                    remaining -= length + 4;

                    byte* chunkData = p;
                    p += length;

                    uint crc = (*(uint*) p).FlipEndianness();
                    p += 4;

                    // todo: check CRC

                    if (compressedDataParts != null && !idatFinished && pChunkBeginning->ChunkType.Value != Helper.IDAT)
                        idatFinished = true;

                    switch (pChunkBeginning->ChunkType.Value)
                    {
                        case Helper.PLTE:
                        {
                            if (Palette != null)
                                throw new InvalidDataException("PLTE chunk appears twice");

                            Palette = new Palette((PaletteEntry*)chunkData, length / 3);
                            break;
                        }
                        case Helper.tRNS:
                        {
                            if (compressedDataParts != null)
                                throw new InvalidDataException("tRNS chunk must precede IDAT change");

                            switch (ColorType)
                            {
                                case ColorType.Grayscale:
                                    if (length != 2)
                                        throw new InvalidDataException("For color type Grayscale, tRNS length must be exactly 2 bytes");
                                    break;
                                case ColorType.TrueColor:
                                    if (length != 6)
                                        throw new InvalidDataException("For color type TrueColor, tRNS length must be exactly 6 bytes");
                                    break;
                                case ColorType.PaletteColor:
                                    if (Palette == null)
                                        throw new InvalidDataException("For color type PaletteColor, PLTE chunk must precede tRNS chunk");
                                    if (length > Palette.Entries.Length)
                                        throw new InvalidDataException("For color type PaletteColor, tRNS chunk length must be less than the number of palette entries");
                                    break;
                                default: throw new InvalidDataException(string.Format("tRNS chunk is not supported by the '{0}' color type", ColorType));
                            }
                            Transparency = new byte[length];
                            Marshal.Copy((IntPtr)chunkData, Transparency, 0, length);
                            break;
                        }
                        case Helper.IDAT:
                        {
                            if (idatFinished)
                                throw new InvalidDataException("IDAT chunks must appear consecutively");

                            compressedDataParts = compressedDataParts ?? new List<PointerLengthPair>();
                            compressedDataParts.Add(new PointerLengthPair{Pointer = (IntPtr)chunkData, Length = length});
                            totalCompressedDataLength += length;
                            break;
                        }
                        case Helper.IEND:
                        {
                            if (length != 0)
                                throw new InvalidDataException("IEND chunk must be empty");

                            endFound = true;
                            break;
                        }
                    }
                }

                if (compressedDataParts == null)
                    throw new InvalidDataException("No mandatory IDAT chunks found");

                var puff = new Puff();
                Data = new byte[Helper.SizeOfFilteredImageData(Width, Height, ColorType, BitDepth)];

                fixed (byte* pData = Data)
                {
                    // todo: check ZLib header

                    uint destLen = (uint)Data.Length;
                    uint sourceLen = (uint) totalCompressedDataLength - 6;

                    var puffResult = puff.DoPuff(pData, &destLen, compressedDataParts, &sourceLen);
                    if (puffResult != 0)
                        throw new InvalidDataException(string.Format("Decompressing the image data failed with the code {0}", puffResult));

                    if (destLen != Data.Length)
                        throw new InvalidDataException(string.Format("Expected decompressed data size was {0}, but {1} were recieved", Data.Length, destLen));
                    if (sourceLen != totalCompressedDataLength - 6)
                        throw new InvalidDataException(string.Format("Expected compressed data size was {0}, but was actually {1}", totalCompressedDataLength, sourceLen));

                    // todo: check ZLib crc
                }
            }

            fixed (byte* pData = Data)
            {
                int numPasses = InterlaceMethod == InterlaceMethod.Adam7 ? 7 : 1;

                for (int pass = 1; pass <= numPasses; pass++)
                {
                    int passWidthInBytes = Helper.SizeOfImageRow(
                        InterlaceMethod == InterlaceMethod.Adam7 ? Helper.InterlacedPassWidth(pass, Width) : Width,
                        ColorType, BitDepth);

                    if (passWidthInBytes != 0)
                    {
                        byte* rawRow = pData;
                        byte* filteredRow = pData;
                        int bpp = Helper.BytesPerPixelCeil(ColorType, BitDepth);

                        // First row
                        var filterType = (FilterType)filteredRow[0]; filteredRow++;
                        switch (filterType)
                        {
                            case FilterType.None:
                                for (int x = 0; x < passWidthInBytes; x++)
                                    rawRow[x] = filteredRow[x];
                                break;
                            case FilterType.Sub:
                                for (int x = 0; x < bpp; x++)
                                    rawRow[x] = filteredRow[x];
                                for (int x = bpp; x < passWidthInBytes; x++)
                                    rawRow[x] = (byte)(filteredRow[x] + rawRow[x - bpp]);
                                break;
                            case FilterType.Up:
                                for (int x = 0; x < passWidthInBytes; x++)
                                    rawRow[x] = filteredRow[x];
                                break;
                            case FilterType.Average:
                                for (int x = 0; x < bpp; x++)
                                    rawRow[x] = filteredRow[x];
                                for (int x = bpp; x < passWidthInBytes; x++)
                                    rawRow[x] = (byte)(filteredRow[x] + rawRow[x - bpp] / 2);
                                break;
                            case FilterType.Parth:
                                for (int x = 0; x < bpp; x++)
                                    rawRow[x] = filteredRow[x];
                                for (int x = bpp; x < passWidthInBytes; x++)
                                    rawRow[x] = (byte)(filteredRow[x] + Helper.PaethPredictor(rawRow[x - bpp], 0, 0));
                                break;
                            default:
                                throw new ArgumentOutOfRangeException("filterType");
                        }

                        // Other rows

                        for (int y = 1; y < Height; y++)
                        {
                            byte* prevRawRow = rawRow;
                            rawRow += passWidthInBytes;
                            filteredRow += passWidthInBytes;

                            filterType = (FilterType)filteredRow[0]; filteredRow++;
                            switch (filterType)
                            {
                                case FilterType.None:
                                    for (int x = 0; x < passWidthInBytes; x++)
                                        rawRow[x] = filteredRow[x];
                                    break;
                                case FilterType.Sub:
                                    for (int x = 0; x < bpp; x++)
                                        rawRow[x] = filteredRow[x];
                                    for (int x = bpp; x < passWidthInBytes; x++)
                                        rawRow[x] = (byte)(filteredRow[x] + rawRow[x - bpp]);
                                    break;
                                case FilterType.Up:
                                    for (int x = 0; x < passWidthInBytes; x++)
                                        rawRow[x] = (byte)(filteredRow[x] + prevRawRow[x]);
                                    break;
                                case FilterType.Average:
                                    for (int x = 0; x < bpp; x++)
                                        rawRow[x] = (byte)(filteredRow[x] + prevRawRow[x] / 2);
                                    for (int x = bpp; x < passWidthInBytes; x++)
                                        rawRow[x] = (byte)(filteredRow[x] + (rawRow[x - bpp] + prevRawRow[x]) / 2);
                                    break;
                                case FilterType.Parth:
                                    for (int x = 0; x < bpp; x++)
                                        rawRow[x] = (byte)(filteredRow[x] + Helper.PaethPredictor(0, prevRawRow[0], 0));
                                    for (int x = bpp; x < passWidthInBytes; x++)
                                        rawRow[x] = (byte)(filteredRow[x] + Helper.PaethPredictor(rawRow[x - bpp], prevRawRow[x], prevRawRow[x - bpp]));
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException("filterType");
                            }
                        }
                    }
                }
            }

            // Done
        }
Esempio n. 10
0
 public override void onAddedToEntity()
 {
     this.puffEntity = (Puff)entity;
 }