source: 2013/30/MiskaK/MW2(My Warfare 2)/Paranneltu Jypeli/Shapes.cs @ 4507

Revision 4507, 24.2 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
1#region MIT License
2/*
3 * Copyright (c) 2009 University of Jyväskylä, Department of Mathematical
4 * Information Technology.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#endregion
25
26/*
27 * Authors: Tero Jäntti, Tomi Karppinen, Janne Nikkanen.
28 */
29
30using System;
31using System.ComponentModel;
32using AdvanceMath;
33using Physics2DDotNet;
34using Physics2DDotNet.Shapes;
35using Microsoft.Xna.Framework;
36using Microsoft.Xna.Framework.Graphics;
37
38using XnaRectangle = Microsoft.Xna.Framework.Rectangle;
39using XnaColor = Microsoft.Xna.Framework.Color;
40using System.Reflection;
41
42
43namespace Jypeli
44{
45    /// <summary>
46    /// Kuvio.
47    /// </summary>
48    public abstract class Shape
49    {
50        /// <summary>
51        /// If true, the shape must be scaled by the size of the object
52        /// that has the shape. Typically, an unit-sized object has width
53        /// and height of 1.0.
54        /// </summary>
55        public abstract bool IsUnitSize { get; }
56
57        internal abstract ShapeCache Cache { get; }
58
59        /// <summary>
60        /// Ympyrä tai ellipsi.
61        /// </summary>
62        public static readonly Ellipse Circle = new Ellipse();
63
64        /// <summary>
65        /// Ellipsi tai ympyrä.
66        /// </summary>
67        public static readonly Ellipse Ellipse = new Ellipse();
68
69        /// <summary>
70        /// Suorakulmio.
71        /// </summary>
72        public static readonly Rectangle Rectangle = new Rectangle();
73
74        /// <summary>
75        /// Tasasivuinen kolmio.
76        /// </summary>
77        public static readonly Triangle Triangle = new Triangle();
78
79        /// <summary>
80        /// Sydän.
81        /// </summary>
82        public static readonly Heart Heart = new Heart();
83
84        /// <summary>
85        /// Tähti.
86        /// </summary>
87        public static readonly Star Star = new Star();
88
89        /// <summary>
90        /// Timantti- / salmiakkikuvio
91        /// </summary>
92        public static readonly Shape Diamond = new RegularPolygon(4);
93
94        /// <summary>
95        /// Pentagoni eli viisikulmio.
96        /// </summary>
97        public static readonly Shape Pentagon = new RegularPolygon( 5 );
98
99        /// <summary>
100        /// Heksagoni eli kuusikulmio.
101        /// </summary>
102        public static readonly Shape Hexagon = new RegularPolygon( 6 );
103
104        /// <summary>
105        /// Oktagoni eli kahdeksankulmio.
106        /// </summary>
107        public static readonly Shape Octagon = new RegularPolygon( 8 );
108
109        /// <summary>
110        /// Luo kuvion annetusta kuvasta. Kuvassa tulee olla vain yksi
111        /// yhtenäinen muoto (toisin sanoen kuvio ei voi koostua monesta osasta).
112        /// </summary>
113        /// <remarks>
114        /// Kuvion luominen voi olla melko hidasta. Kannattaa luoda kuvio heti pelin alussa
115        /// ja käyttää kerran luotua kuviota kaikille olioille.
116        /// </remarks>
117        /// <param name="image">Kuva, josta muoto luetaan.</param>
118        public static Shape FromImage( Image image )
119        {
120            Texture2D texture = image.XNATexture;
121            IBitmap bm = new TextureBitmap( texture );
122            Vector2D[] vertices = VertexHelper.CreateFromBitmap( bm );
123
124            for ( int i = 0; i < vertices.Length; i++ )
125            {
126                vertices[i].X /= texture.Width;
127                vertices[i].Y /= texture.Height;
128
129                // The center of the texture coordinates is at top left corner, but the center of
130                // game objects is by default at the center of the object.
131                vertices[i] -= new Vector2D( (float)0.5, (float)0.5 );
132            }
133
134            Vector[] polygonVertices = new Vector[vertices.Length];
135            for ( int i = 0; i < vertices.Length; i++ )
136                polygonVertices[i] = new Vector( vertices[i].X, vertices[i].Y );
137
138            ShapeCache cache = new ShapeCache( polygonVertices );
139            return new Polygon( cache );
140        }
141
142        /// <summary>
143        /// Luo muodon merkkijonosta, esim. "Circle"
144        /// </summary>
145        /// <returns></returns>
146        public static Shape FromString( string shapeStr )
147        {
148            Type shapeClass = typeof( Shape );
149            BindingFlags flags = BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static;
150            FieldInfo selectedShape = shapeClass.GetField( shapeStr, flags );
151            return (Shape)selectedShape.GetValue( null );
152        }
153
154        /// <summary>
155        /// Luo säännöllisen monikulmion (polygonin)
156        /// </summary>
157        /// <param name="vertexCount">Kulmapisteiden määrä (3=kolmio, 4=neliö jne.)</param>
158        /// <returns>Monikulmio</returns>
159        public static Shape CreateRegularPolygon( int vertexCount )
160        {
161            if ( vertexCount < 3 ) throw new ArgumentException( "You need at least 3 vertices to create a polygon!" );
162            return new RegularPolygon( vertexCount );
163        }
164
165        internal static ShapeCache CreateRegularPolygonCache( int vertexCount )
166        {
167            double angleStep = 2 * Math.PI / vertexCount;
168            Int16 centerIndex = (Int16)vertexCount;
169
170            Vector[] vertices = new Vector[vertexCount + 1];
171            IndexTriangle[] triangles = new IndexTriangle[vertexCount];
172            Int16[] outlineIndices = new Int16[vertexCount];
173
174            for ( int i = 0; i < vertexCount; i++ )
175            {
176                double a = i * angleStep;
177                vertices[i] = new Vector( 0.5 * Math.Cos( a ), 0.5 * Math.Sin( a ) );
178                outlineIndices[i] = (Int16)i;
179            }
180            vertices[centerIndex] = Vector.Zero;
181
182            for ( int i = 0; i < vertexCount - 1; i++ )
183            {
184                triangles[i] = new IndexTriangle( (Int16)i, centerIndex, (Int16)( i + 1 ) );
185            }
186            triangles[vertexCount - 1] = new IndexTriangle( (Int16)( vertexCount - 1 ), centerIndex, (Int16)0 );
187
188            return new ShapeCache( vertices, triangles, outlineIndices );
189        }
190
191        protected static bool SameSide( Vector a, Vector b, Vector p1, Vector p2 )
192        {
193            double cp1 = Vector.CrossProduct( b - a, p1 - a );
194            double cp2 = Vector.CrossProduct( b - a, p2 - a );
195            return cp1 * cp2 >= 0;
196        }
197
198        protected static bool IsInsideTriangle( Vector p, Vector a, Vector b, Vector c )
199        {
200            Vector v0 = c - a;
201            Vector v1 = b - a;
202            Vector v2 = p - a;
203
204            // Dot products between each side
205            double dot00 = Vector.DotProduct( v0, v0 );
206            double dot01 = Vector.DotProduct( v0, v1 );
207            double dot02 = Vector.DotProduct( v0, v2 );
208            double dot11 = Vector.DotProduct( v1, v1 );
209            double dot12 = Vector.DotProduct( v1, v2 );
210
211            // Barycentric coordinates
212            double invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
213            double u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
214            double v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
215
216            return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );
217        }
218
219        // TODO: Benchmark these two methods and use as default that which is faster
220
221        protected bool IsInsideTriangles( Vector p )
222        {
223            for ( int i = 0; i < Cache.Triangles.Length; i++ )
224            {
225                Vector t1 = Cache.Vertices[Cache.Triangles[i].i1];
226                Vector t2 = Cache.Vertices[Cache.Triangles[i].i2];
227                Vector t3 = Cache.Vertices[Cache.Triangles[i].i3];
228
229                if ( IsInsideTriangle( p, t1, t2, t3 ) )
230                    return true;
231            }
232
233            return false;
234        }
235
236        protected bool IsInsideOutlines( Vector p )
237        {
238            Vector a, b;
239
240            for ( int i = 0; i < Cache.OutlineVertices.Length - 1; i++ )
241            {
242                a = Cache.OutlineVertices[i];
243                b = Cache.OutlineVertices[i + 1];
244
245                if ( !SameSide( a, b, p, Vector.Zero ) )
246                    return false;
247            }
248
249            a = Cache.OutlineVertices[Cache.OutlineVertices.Length - 1];
250            b = Cache.OutlineVertices[0];
251            if ( !SameSide( a, b, p, Vector.Zero ) )
252                return false;
253
254            return true;
255        }
256
257        protected bool IsInsideCircle( double x, double y, double r )
258        {
259            return x * x + y * y <= r;
260        }
261       
262        /// <summary>
263        /// Onko piste muodon sisällä.
264        /// Pisteen koordinaatiston origo on muodon keskellä.
265        /// Muoto on kokoa 1x1 jos IsUnitSize, muuten saman kokoinen kuin olio.
266        /// </summary>
267        /// <param name="x">X-koordinaatti</param>
268        /// <param name="y">Y-koordinaatti</param>
269        /// <returns>Onko piste muodon sisällä</returns>
270        public virtual bool IsInside( double x, double y )
271        {
272            if ( Cache != null && Cache.Triangles != null )
273            {
274                // Use the shape cache triangles
275                return IsInsideTriangles( new Vector( x, y ) );
276            }
277            else if ( Cache != null && Cache.OutlineVertices != null )
278            {
279                // Use the shape cache outlines
280                return IsInsideOutlines( new Vector( x, y ) );
281            }
282            else
283            {
284                // Default: use the equation for a circle
285                return IsInsideCircle( x, y, 1 );
286            }
287        }
288    }
289
290    /// <summary>
291    /// Ympyrä.
292    /// </summary>
293    public class Ellipse : Shape
294    {
295        private static ShapeCache _cache = CreateRegularPolygonCache( 64 );
296
297        internal override ShapeCache Cache
298        {
299            get { return _cache; }
300        }
301
302        public override bool IsUnitSize { get { return true; } }
303
304        internal Ellipse() { }
305
306        public override bool IsInside( double x, double y )
307        {
308            return IsInsideCircle( x, y, 1 );
309        }
310    }
311
312    /// <summary>
313    /// Suorakulmio.
314    /// </summary>
315    public class Rectangle : Shape
316    {
317        private static readonly Vector[] vertices = new Vector[]
318        {
319            new Vector( -0.5, -0.5 ),
320            new Vector( -0.5, 0.5 ),
321            new Vector( 0.5, -0.5 ),
322            new Vector( 0.5, 0.5 ),
323        };
324
325        private static readonly IndexTriangle[] triangles = new IndexTriangle[]
326        {
327            new IndexTriangle( 0, 1, 2 ),
328            new IndexTriangle( 2, 1, 3 ),
329        };
330
331        private static readonly Int16[] outlineIndices = new Int16[]
332        {
333            2, 3, 1, 0
334        };
335
336        private static readonly ShapeCache _cache = new ShapeCache( vertices, triangles, outlineIndices );
337
338        internal override ShapeCache Cache { get { return _cache; } }
339
340        public override bool IsUnitSize { get { return true; } }
341
342        internal Rectangle() { }
343
344        public override bool IsInside( double x, double y )
345        {
346            return ( Math.Abs( x ) <= 1 && Math.Abs( y ) <= 1 );
347        }
348    }
349
350    /// <summary>
351    /// Sydän.
352    /// </summary>
353    public class Heart : Shape
354    {
355        private static readonly Vector[] vertices = new Vector[]
356        {
357            new Vector( 0, -0.5 ),
358            new Vector( 0.5, 0.2 ),
359            new Vector( 0.4, 0.4 ),
360            new Vector( 0.25, 0.5 ),
361            new Vector( 0.1, 0.4 ),
362            new Vector( 0, 0.2 ),
363            new Vector( -0.1, 0.4 ),
364            new Vector( -0.25, 0.5 ),
365            new Vector( -0.4, 0.4 ),
366            new Vector( -0.5, 0.2 )
367       };
368
369        private static readonly IndexTriangle[] triangles = new IndexTriangle[]
370        {
371            new IndexTriangle( 0, 9, 5 ),
372            new IndexTriangle( 8, 7, 6 ),
373            new IndexTriangle( 8, 6, 5 ),
374            new IndexTriangle( 9, 8, 5 ),
375            new IndexTriangle( 3, 2, 4 ),
376            new IndexTriangle( 4, 2, 5 ),
377            new IndexTriangle( 2, 1, 5 ),
378            new IndexTriangle( 5, 1, 0 ),
379        };
380
381        private static readonly ShapeCache _cache = new ShapeCache( vertices, triangles );
382
383        internal override ShapeCache Cache { get { return _cache; } }
384
385        public override bool IsUnitSize { get { return true; } }
386
387        internal Heart() { }
388    }
389
390    /// <summary>
391    /// Tähti.
392    /// </summary>
393    public class Star : Shape
394    {
395        private static readonly Vector[] vertices = new Vector[]
396        {
397            new Vector( -0.5, -0.5 ),
398            new Vector( -0.25, 0 ),
399            new Vector( 0, -0.16 ),
400            new Vector( -0.5, 0.2 ),
401            new Vector( -0.15, 0.2 ),
402            new Vector( 0, 0.5 ),
403            new Vector( 0.15, 0.2 ),
404            new Vector( 0.5, 0.2 ),
405            new Vector( 0.25, 0 ),
406            new Vector( 0.5, -0.5 ),
407        };
408
409        private static readonly IndexTriangle[] triangles = new IndexTriangle[]
410        {
411            new IndexTriangle( 0, 1, 2 ),
412            new IndexTriangle( 1, 3, 4 ),
413            new IndexTriangle( 1, 5, 8 ),
414            new IndexTriangle( 8, 6, 7 ),
415            new IndexTriangle( 9, 2, 8 ),
416            new IndexTriangle( 1, 8, 2 ),
417        };
418
419        private static readonly Int16[] outlineIndices = new Int16[]
420        {
421            2, 9, 8, 7, 6, 5, 4, 3, 1, 0
422        };
423
424        private static readonly ShapeCache _cache = new ShapeCache( vertices, triangles, outlineIndices );
425
426        internal override ShapeCache Cache { get { return _cache; } }
427
428        public override bool IsUnitSize { get { return true; } }
429
430        internal Star() { }
431    }
432
433    /// <summary>
434    /// Tasasivuinen kolmio.
435    /// </summary>
436    public class Triangle : Shape
437    {
438        private static readonly Vector[] vertices = new Vector[]
439        {
440            new Vector( 0, 0.5 ),
441            new Vector( 0.5, -0.5 ),
442            new Vector( -0.5, -0.5 ),
443        };
444
445        private static readonly IndexTriangle[] triangles = new IndexTriangle[]
446        {
447            new IndexTriangle( 0, 1, 2 ),
448        };
449
450        private static readonly Int16[] outlineIndices = new Int16[]
451        {
452            2, 1, 0
453        };
454
455        private static readonly ShapeCache _cache = new ShapeCache( vertices, triangles, outlineIndices );
456
457        internal override ShapeCache Cache { get { return _cache; } }
458
459        public override bool IsUnitSize { get { return true; } }
460
461        internal Triangle() { }       
462
463        public override bool IsInside( double x, double y )
464        {
465            return IsInsideTriangle( new Vector( x, y ), vertices[0], vertices[1], vertices[2] );
466        }
467    }
468
469    /// <summary>
470    /// Jana.
471    /// </summary>
472    public class RaySegment : Shape
473    {
474        internal override ShapeCache Cache
475        {
476            get { throw new Exception( "Cache is not defined for RaySegment" ); }
477        }
478
479        public override bool IsUnitSize { get { return false; } }
480
481        public Vector Origin;
482        public Vector Direction;
483        public double Length;
484
485        public RaySegment( Vector origin, Vector direction, double length )
486        {
487            this.Origin = origin;
488            this.Direction = direction;
489            this.Length = length;
490        }
491    }
492
493    /// <summary>
494    /// Monikulmio.
495    /// </summary>
496    public class Polygon : Shape
497    {
498        private bool isUnitSize = true;
499        private ShapeCache _cache;
500
501        /// <summary>
502        /// If true, the shape must be scaled by the size of the object
503        /// that has the shape. Typically, an unit-sized object has width
504        /// and height of 1.0.
505        /// </summary>
506        public override bool IsUnitSize
507        {
508            get { return isUnitSize; }
509        }
510
511        internal override ShapeCache Cache
512        {
513            get { return _cache; }
514        }
515
516        public Polygon( ShapeCache cache )
517            : this( cache, true )
518        {
519        }
520
521        public Polygon( ShapeCache cache, bool isUnitSize )
522        {
523            this._cache = cache;
524            this.isUnitSize = isUnitSize;
525        }
526    }
527
528    /// <summary>
529    /// Säännöllinen monikulmio.
530    /// </summary>
531    internal class RegularPolygon : Polygon
532    {
533        public int CornerCount { get; internal set; }
534        public override bool IsUnitSize { get { return true; } }
535
536        public RegularPolygon( int vertexCount )
537            : base( CreateRegularPolygonCache( vertexCount ) )
538        {
539            CornerCount = vertexCount;
540        }
541    }
542
543    /// <summary>
544    /// Muotojen määrityksessä käytettävä kolmio.
545    /// </summary>
546    [EditorBrowsable( EditorBrowsableState.Never )]
547    public struct IndexTriangle
548    {
549        /// <summary>
550        /// Kulmapisteet.
551        /// </summary>
552        public Int16 i1, i2, i3;
553
554        /// <summary>
555        /// Luo uuden kolmion. Parametreina kulmapisteiden indeksit lueteltuna myötäpäivään.
556        /// </summary>
557        public IndexTriangle( Int16 i1, Int16 i2, Int16 i3 )
558        {
559            this.i1 = i1;
560            this.i2 = i2;
561            this.i3 = i3;
562        }
563
564        /// <summary>
565        /// Luo uuden kolmion. Parametreina kulmapisteiden indeksit lueteltuna myötäpäivään.
566        /// </summary>
567        public IndexTriangle( int i1, int i2, int i3 )
568            : this( (Int16)i1, (Int16)i2, (Int16)i3 )
569        {
570        }
571    }
572
573    /// <summary>
574    /// Sisältää valmiiksi lasketut kolmiot, joiden avulla piirtäminen on suoraviivaista.
575    /// </summary>
576    [EditorBrowsable( EditorBrowsableState.Never )]
577    public class ShapeCache
578    {
579        // The vertices are in counter-clockwise order
580        // because that is what the polygon shape of the physics
581        // engine expects.
582
583        /// <summary>
584        /// Ulkoreunan verteksit, lueteltuna vastapäivään.
585        /// </summary>
586        public readonly Vector[] OutlineVertices;
587
588        /// <summary>
589        /// Kaikki verteksit, ml. kolmioiden kulmapisteet.
590        /// </summary>
591        public readonly Vector[] Vertices;
592
593        /// <summary>
594        /// Kolmiot, joiden avulla kuvio voidaan täyttää värillä.
595        /// </summary>
596        public readonly IndexTriangle[] Triangles;
597
598        /// <summary>
599        /// Luo kuvion kolmioilla, joiden avulla kuvio voidaan täyttää värillä. Kaikkien
600        /// verteksien tulee olla kuvion ulkoreunalla.
601        /// </summary>
602        /// <param name="outlineVertices">Ulkoreunan verteksit, lueteltuna vastapäivään.</param>
603        /// <param name="triangles">Kolmiot.</param>
604        public ShapeCache( Vector[] outlineVertices, IndexTriangle[] triangles )
605        {
606            this.Vertices = this.OutlineVertices = outlineVertices;
607            Triangles = triangles;
608        }
609
610        /// <summary>
611        /// Luo kuvion pelkillä reuna-vertekseillä. Kuviolle ei tule tietoa kolmioista,
612        /// näin ollen sitä ei voi täyttää värillä.
613        /// </summary>
614        /// <param name="outlineVertices">Ulkoreunan verteksit, lueteltuna vastapäivään.</param>
615        public ShapeCache( Vector[] outlineVertices )
616        {
617            this.Vertices = this.OutlineVertices = outlineVertices;
618            this.Triangles = null;
619        }
620
621        /// <summary>
622        /// Luo kuvion, joka voidaan piirtää täytettynä värillä.
623        /// </summary>
624        /// <param name="vertices">Kaikki verteksit (ml. reunan verteksit sekä kolmioiden verteksit).</param>
625        /// <param name="triangles">Kolmiot, joista kuvio koostuu.</param>
626        /// <param name="outlineIndices">Ulkoreunan verteksit lueteltuna vastapäivään, indekseinä <c>vertices</c>-taulukkoon.</param>
627        public ShapeCache( Vector[] vertices, IndexTriangle[] triangles, Int16[] outlineIndices )
628        {
629            Vertices = vertices;
630            Triangles = triangles;
631
632            OutlineVertices = new Vector[outlineIndices.Length];
633            for ( int i = 0; i < outlineIndices.Length; i++ )
634            {
635                OutlineVertices[i] = vertices[outlineIndices[i]];
636            }
637        }
638    }
639
640    /// <summary>
641    /// Tekstuuribittikartta muotojen luomiseen tekstuureista.
642    /// Sisältää tekstuurin tiedot väritaulukkona.
643    /// </summary>
644    internal class TextureBitmap : IBitmap
645    {
646        /// <summary>
647        /// Bittikarttadata.
648        /// </summary>
649        protected bool[,] bitmap;
650
651        /// <summary>
652        /// Luo uuden bittikartan tekstuurin pohjalta.
653        /// </summary>
654        /// <param name="texture">Tekstuuri.</param>
655        /// <param name="isOpaque">Predikaatti, joka määrää, onko annettu väri läpinäkyvä.</param>
656        public TextureBitmap( Texture2D texture, Predicate<XnaColor> isOpaque )
657        {
658            XnaColor[] scanline = new XnaColor[texture.Width];
659            XnaRectangle srcRect = new XnaRectangle( 0, 0, texture.Width, 1 );
660
661            bitmap = new bool[texture.Width, texture.Height];
662
663            for ( int i = 0; i < texture.Height; i++ )
664            {
665                // Scan a line from the texture
666                srcRect.Y = i;
667                texture.GetData<XnaColor>( 0, srcRect, scanline, 0, texture.Width );
668
669                for ( int j = 0; j < texture.Width; j++ )
670                {
671                    // Flip the y-coordinates because the y-coordinates of the texture
672                    // increase downwards.
673                    bitmap[j, texture.Height - i - 1] = isOpaque( scanline[j] );
674                }
675            }
676        }
677
678        /// <summary>
679        /// Luo uuden bittikartan tekstuurin pohjalta oletusläpinäkyvyysehdoilla.
680        /// Ks. <see cref="IsOpaqueColor"/>
681        /// </summary>
682        /// <param name="texture">Tekstuuri.</param>
683        public TextureBitmap( Texture2D texture )
684            : this( texture, IsOpaqueColor )
685        {
686        }
687
688        /// <summary>
689        /// Bittikartan leveys pikseleinä.
690        /// </summary>
691        public int Width
692        {
693            get { return bitmap.GetLength( 0 ); }
694        }
695
696        /// <summary>
697        /// Bittikartan korkeus pikseleinä.
698        /// </summary>
699        public int Height
700        {
701            get { return bitmap.GetLength( 1 ); }
702        }
703
704        /// <summary>
705        /// Palauttaa yksittäisen pikselin värin annetusta koordinaattipisteestä (ensin x, sitten y).
706        /// </summary>
707        public bool this[int x, int y]
708        {
709            get
710            {
711                if ( x < 0 || y < 0 || x >= Width || y >= Height ) { return false; }
712                return bitmap[x, y];
713            }
714        }
715
716        /// <summary>
717        /// Päättelee pikselin läpinäkyvyyden sen värin perusteella.
718        /// Tässä tapauksessa alfa-arvon tulee olla suurempi tai yhtäsuuri kuin 127.
719        /// </summary>
720        /// <param name="c">Pikselin väri.</param>       
721        /// <returns>Läpinäkyvyys.</returns>
722        public static bool IsOpaqueColor( XnaColor c )
723        {
724            return ( c.A >= 127 );
725        }
726    }
727}
Note: See TracBrowser for help on using the repository browser.