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); }
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(); }
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; }
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; } }
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 }
public override void onAddedToEntity() { this.puffEntity = (Puff)entity; }