Пример #1
0
 protected GenFragmentGenerator(GenDataDef genDataDef, GenWriter writer, Fragment fragment, GenObject genObject)
 {
     _genDataDef = genDataDef;
     _writer     = writer;
     _fragment   = fragment;
     GenObject   = genObject;
 }
Пример #2
0
        public void RefreshProfile(GenDataBase genDataBase, GenObject genObject)
        {
            var selectedItem = ProfileNavigatorTreeView.SelectedNode;
            var dataProfile  = GenDataEditorViewModel.Data.Profile;

            dataProfile.Fragment = ProfileEditorTreeViewBuilder.GetNodeData(selectedItem);
            var text = dataProfile.GetNodeProfileText();

            // Don't change to prevent unnecessary rendering and side effects
            if (text != ProfileTextBox.Text)
            {
                var start = ProfileTextBox.SelectionStart;
                ProfileTextBox.Clear();
                ProfileTextBox.Text           = text;
                ProfileTextBox.SelectionStart = start;
            }


            text = dataProfile.GetNodeExpansionText(genDataBase, genObject);

            // Don't change to prevent unnecessary rendering and side effects
            if (text != ProfileExpansionTextBox.Text)
            {
                var start = ProfileExpansionTextBox.SelectionStart;
                ProfileExpansionTextBox.Clear();
                ProfileExpansionTextBox.Text           = text;
                ProfileExpansionTextBox.SelectionStart = start;
            }
        }
Пример #3
0
 public GenSegmentGenerator(GenDataDef genDataDef, GenWriter genWriter, GenObject genObject, Fragment fragment)
     : base(genDataDef, genWriter, genObject, fragment)
 {
     Segment        = (Segment)fragment;
     GenCardinality = Segment.GenCardinality;
     Navigator      = new SegmentNavigator(this);
 }
Пример #4
0
        public void GenLookupContextTest()
        {
            var d = SetUpLookupContextData();
            var f = d.GenDataDef;
            var r = new GenProfileFragment(new GenProfileParams(GenData.GenDataDef));

            var b  = new GenBlock(new GenFragmentParams(f, r));
            var p0 = new GenPlaceholderFragment(new GenPlaceholderFragmentParams(f, b, f.GetId("Parent.Name")));
            var t0 = new GenTextFragment(new GenTextFragmentParams(f, b, ","));

            b.Body.Add(p0);
            b.Body.Add(t0);

            var g  = new GenLookup(new GenLookupParams(f, b, "Lookup.Name=Child.Lookup"));
            var p1 = new GenPlaceholderFragment(new GenPlaceholderFragmentParams(f, g, f.GetId("Lookup.Name")));
            var t1 = new GenTextFragment(new GenTextFragmentParams(f, g, ","));

            Assert.IsFalse(g.NoMatch);

            b.Body.Add(g);
            g.Body.Add(p1);
            g.Body.Add(t1);

            var parent = GenObject.GetContext(d.Root, "Parent");
            var child  = GetFirstObjectOfSubClass(parent, "Child");

            b.GenObject = child;
            VerifyFragment(d, b, "GenBlock", FragmentType.Block, "Block",
                           "`{`Parent.Name`,`%Lookup.Name=Child.Lookup:`Lookup.Name`,`]`]", "Parent,Valid,", false, null, r.Profile.GenDataBase.GenDataDef);

            child       = GetLastObjectInSubClass(child);
            b.GenObject = child;
            VerifyFragment(d, b, "GenBlock", FragmentType.Block, "Block",
                           "`{`Parent.Name`,`%Lookup.Name=Child.Lookup:`Lookup.Name`,`]`]", "Parent,", false, null, r.Profile.GenDataBase.GenDataDef);
        }
Пример #5
0
 public static string ExpandSecondary(GenDataDef genDataDef, GenObject genObject, Fragment fragment)
 {
     if (fragment is ContainerFragment)
     {
         return(Create(genDataDef, genObject, fragment).ExpandSecondary());
     }
     return("");
 }
Пример #6
0
 protected static GenObject GetLastObjectInSubClass(GenObject genObject)
 {
     if (genObject.ParentSubClass.Count == 0)
     {
         return(null);
     }
     return(genObject.ParentSubClass[genObject.ParentSubClass.Count - 1]);
 }
Пример #7
0
        public void  VerifyParentChildReferenceGetValue()
        {
            var dataChild  = SetUpParentChildData("Child", "Grandchild", "Grandchild");
            var dataParent = SetUpParentChildReferenceData("Parent", "Child", "Child", "Child", dataChild);
            var genObject  = GenObject.GetContext(dataParent.Root, "GrandChild");
            var id         = dataParent.GenDataDef.GetId("Parent", "Name");

            Assert.AreEqual("Parent", genObject.GetValue(id));
        }
Пример #8
0
        /// <summary>
        /// A constraint used to link two objects together, and push or pull them until they are a specified distance apart.
        /// Each link point is offset to the center point of its connected object by default.
        /// </summary>
        /// <param name="pointA">The first object to use as a connection point.</param>
        /// <param name="pointB">The second object to use as a connection point.</param>
        public GenLink(GenObject pointA, GenObject pointB)
        {
            Stiffness = 1f;
            TearDistance = 0f;
            PointA = pointA;
            PointB = pointB;

            _restingDistance = Vector2.Distance(PointA.OriginPosition, PointB.OriginPosition);
        }
Пример #9
0
        protected static GenObject GetNextObjectInSubClass(GenObject genObject)
        {
            var i = genObject.ParentSubClass.IndexOf(genObject);

            if (i > genObject.ParentSubClass.Count)
            {
                return(null);
            }
            return(genObject.ParentSubClass[i + 1]);
        }
Пример #10
0
        /// <summary>
        /// Set the subclass reference.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="subClassName">The childe class name.</param>
        /// <param name="reference">The reference path.</param>
        private static void SetSubClassReference(GenObject parent, string subClassName, string reference)
        {
            var subClassIndex = parent.Definition.SubClasses.IndexOf(subClassName);
            var sub           = parent.SubClass[subClassIndex] as SubClassReference;

            if (sub != null)
            {
                sub.Reference = reference;
            }
        }
Пример #11
0
    public static void DelegateTest <U>()
    {
        IGen <object> obj = new GenObject();
        ThreadStart   d   = new ThreadStart(obj.Target <U>);


        d();
        Test.Eval(Test.Xcounter == 1);
        Test.Xcounter = 0;
    }
Пример #12
0
        public void TestObjectContextOfSiblingWithInheritance()
        {
            var dataFile         = GetTestDataFileName("InheritanceDataSaveTest");
            var d                = PopulateInheritanceData(dataFile);
            var container        = GetFirstObject(d);
            var @virtual1        = GetFirstObjectOfSubClass(container, "Abstract");
            var containerContext = GenObject.GetContext(container, "Abstract");

            Assert.AreSame(@virtual1, containerContext);
        }
        public void ContextNoReferencePropertyExistsNoReferenceTest()
        {
            var f = GenDataDef.CreateMinimal();
            var d = new GenDataBase(f);

            SetUpData(d);
            var genObject = GenObject.GetContext(d.Root, "Class");
            var id        = f.GetId("Class.Reference");

            Assert.AreEqual("", genObject.GetValue(id));
        }
Пример #14
0
        public static GenObject CreateDefinitionSubClass(GenObject @class, string name, string reference,
                                                         string relationship)
        {
            var subClass = new GenObject(@class, @class.SubClass[0], 2);

            SetAttribute(subClass, 0, name);
            SetAttribute(subClass, 1, reference);
            SetAttribute(subClass, 2, relationship);
            @class.SubClass[0].Add(subClass);
            return(subClass);
        }
Пример #15
0
 private static void SetAttribute(GenObject genObject, int index, string value)
 {
     if (genObject.Attributes.Count == index)
     {
         genObject.Attributes.Add(value);
     }
     else
     {
         genObject.Attributes[index] = value;
     }
 }
Пример #16
0
        private MuTruncatedGen(GenObject o, double[] range, double muMean, double sigma)
        {
            SGNFnAParam A = o.A.Clone();

            A.MuMean = muMean;
            A.S      = sigma;
            A.S2     = sigma * sigma;
            Icdf icdf = new Icdf(o, A, range);

            this.Mu = icdf.Bidon();
        }
Пример #17
0
        public void TestObjectContextOfChild()
        {
            var d      = SetUpParentChildData("Parent", "Child", "FirstChild");
            var parent = GetFirstObject(d);
            var child  = GetFirstObjectOfSubClass(parent, "Child");

            var parentContext = GenObject.GetContext(parent, "Child");

            Assert.AreSame(child, parentContext);
            parentContext = GenObject.GetContext(parent, "CHILD"); // Case independent search
            Assert.AreSame(child, parentContext);
        }
Пример #18
0
        public void ContextWithReferenceTests()
        {
            var dataChild  = SetUpParentChildData("Child", "Grandchild", "Grandchild");
            var dataParent = SetUpParentChildReferenceData("Parent", "Child", "Child", "Child", dataChild);

            for (var i = 1; i < dataParent.GenDataDef.Classes.Count; i++)
            {
                var genObject = GenObject.GetContext(dataParent.Root, dataParent.GenDataDef.Classes[i].Name);
                Assert.IsNotNull(genObject, i + ": " + dataParent.GenDataDef.Classes[i].Name);
                Assert.AreEqual(genObject.ParentSubClass.Definition.SubClass.RefClassId, genObject.ClassId);
            }
        }
Пример #19
0
        public void TestObjectContextOfAReferenceObjectFromParent()
        {
            var dataChild  = SetUpParentChildData("Child", "Grandchild", "Grandchild");
            var dataParent = SetUpParentChildReferenceData("Parent", "Child", "Child", "Child", dataChild);
            var parent     = GetFirstObject(dataParent);
            var grandchild = GetFirstObjectOfSubClass(GetFirstObject(dataChild), "GrandChild");

            Assert.IsNotNull(grandchild);
            var granddhildContext = GenObject.GetContext(parent, "Grandchild");

            Assert.AreSame(grandchild, granddhildContext);
        }
Пример #20
0
        protected static void CheckOrder(GenDataBase d1, string order, string action)
        {
            var d  = d1;
            var id = d.GenDataDef.GetId("SubClass.Name");
            var s0 = GenObject.GetContext(d.Root, "SubClass");
            var s1 = GetNextObjectInSubClass(s0);
            var s2 = GetNextObjectInSubClass(s1);

            Assert.AreEqual("SubClass" + order[0], s0.GetValue(id), action + " first item");
            Assert.AreEqual("SubClass" + order[1], s1.GetValue(id), action + " second item");
            Assert.AreEqual("SubClass" + order[2], s2.GetValue(id), action + " third item");
        }
Пример #21
0
    public static int Main()
    {
        Outer.IGen <int> IGenInt = new GenInt();
        IGenInt._Init(new int());
        Eval(IGenInt.InstVerify(typeof(int)));

        Outer.IGen <double> IGenDouble = new GenDouble();
        IGenDouble._Init(new double());
        Eval(IGenDouble.InstVerify(typeof(double)));

        Outer.IGen <string> IGenString = new GenString();
        IGenString._Init("string");
        Eval(IGenString.InstVerify(typeof(string)));

        Outer.IGen <object> IGenObject = new GenObject();
        IGenObject._Init(new object());
        Eval(IGenObject.InstVerify(typeof(object)));

        Outer.IGen <Guid> IGenGuid = new GenGuid();
        IGenGuid._Init(new Guid());
        Eval(IGenGuid.InstVerify(typeof(Guid)));

        Outer.IGen <RefX1 <int> > IGenConstructedReference = new GenConstructedReference();
        IGenConstructedReference._Init(new RefX1 <int>());
        Eval(IGenConstructedReference.InstVerify(typeof(RefX1 <int>)));

        Outer.IGen <ValX1 <string> > IGenConstructedValue = new GenConstructedValue();
        IGenConstructedValue._Init(new ValX1 <string>());
        Eval(IGenConstructedValue.InstVerify(typeof(ValX1 <string>)));

        Outer.IGen <int[]> IGen1DIntArray = new Gen1DIntArray();
        IGen1DIntArray._Init(new int[1]);
        Eval(IGen1DIntArray.InstVerify(typeof(int[])));

        Outer.IGen <string[, ]> IGen2DStringArray = new Gen2DStringArray();
        IGen2DStringArray._Init(new string[1, 1]);
        Eval(IGen2DStringArray.InstVerify(typeof(string[, ])));

        Outer.IGen <object[][]> IGenJaggedObjectArray = new GenJaggedObjectArray();
        IGenJaggedObjectArray._Init(new object[1][]);
        Eval(IGenJaggedObjectArray.InstVerify(typeof(object[][])));

        if (result)
        {
            Console.WriteLine("Test Passed");
            return(100);
        }
        else
        {
            Console.WriteLine("Test Failed");
            return(1);
        }
    }
        public void ContextNoFirstPropertyExistsSecondTest()
        {
            var f = GenDataDef.CreateMinimal();
            var d = new GenDataBase(f);

            SetUpData(d);
            CreateGenObject(d.Root, "Class", "Class0");
            var genObject = GetNextObjectInSubClass(GenObject.GetContext(d.Root, "Class"));
            var id        = f.GetId("Class.First");

            Assert.AreEqual("", genObject.GetValue(id));
        }
Пример #23
0
        public static GenObject CreateDefinitionClass(GenObject root, string name, string title, string inheritance,
                                                      GenDataBase d)
        {
            var @class = new GenObject(root, root.SubClass[0], 1);

            SetAttribute(@class, 0, name);
            SetAttribute(@class, 1, title);
            SetAttribute(@class, 2, inheritance);
            @class.SubClass.Add(new GenSubClass(d, @class, 2, null));
            @class.SubClass.Add(new GenSubClass(d, @class, 3, null));
            root.SubClass[0].Add(@class);
            return(@class);
        }
        public void ContextEmptyFirstPropertyExistsTest()
        {
            var f = GenDataDef.CreateMinimal();

            f.AddClassInstanceProperty(1, "First");
            var d = new GenDataBase(f);

            SetUpData(d);
            var genObject = GenObject.GetContext(d.Root, "Class");
            var id        = f.GetId("Class.First");

            Assert.AreEqual("", genObject.GetValue(id));
        }
        public void ContextReferencePropertyExistsWithValueTest()
        {
            var f   = GenDataDef.CreateMinimal();
            var idx = f.AddClassInstanceProperty(1, "Reference");
            var d   = new GenDataBase(f);

            SetUpData(d);
            var id        = f.GetId("Class.Reference");
            var genObject = GenObject.GetContext(d.Root, "Class");

            genObject.Attributes[idx] = "Reference value";
            Assert.AreEqual("Reference value", genObject.GetValue(id));
        }
Пример #26
0
    public static void ThreadPoolTest()
    {
        ManualResetEvent evt = new ManualResetEvent(false);

        IGen <object> obj = new GenObject();

        TimerCallback tcb   = new TimerCallback(obj.Target);
        Timer         timer = new Timer(tcb, evt, Test_thread15.delay, Test_thread15.period);

        evt.WaitOne();
        timer.Dispose();
        Test_thread15.Eval(Test_thread15.Xcounter >= Test_thread15.nThreads);
        Test_thread15.Xcounter = 0;
    }
Пример #27
0
        public void VerifySetUpParentChildDataMethod()
        {
            var d = SetUpParentChildData("Parent", "Child", "Child");
            var f = d.GenDataDef;

            Assert.AreEqual(3, f.Classes.Count);
            Assert.AreEqual("Parent", f.GetClassName(1));
            Assert.AreEqual("Child", f.GetClassName(2));
            Assert.AreEqual(1, f.GetClassSubClasses(1).Count);
            Assert.AreEqual(2, f.GetClassSubClasses(1)[0].SubClass.ClassId);
            Assert.AreEqual("", f.GetClassSubClasses(1)[0].Reference);
            Assert.AreEqual("Parent", GenObject.GetContext(d.Root, "Parent").Attributes[0]);
            Assert.AreEqual("Child", GenObject.GetContext(d.Root, "Child").Attributes[0]);
        }
Пример #28
0
        protected static GenObject GetFirstObjectOfSubClass(GenObject genObject, string subClassName)
        {
            Contract.Requires(genObject != null, "The object cannot be null");
            Contract.Requires(genObject.Definition != null, "The object definition is required");
            var index = genObject.Definition.IndexOfSubClass(subClassName);

            if (index == -1)
            {
                throw new ArgumentException("Class is not a subclass", subClassName);
            }
            var subClass = genObject.GetSubClass(subClassName);

            return(subClass.Count == 0 ? null : subClass[0]);
        }
Пример #29
0
 /// <summary>
 /// Initializes a new instance of the GenObjectViewModel class.
 /// </summary>
 /// <param name="genObject">The <see cref="GenObject"/> being edited.</param>
 /// <param name="definition">The class definition of the object being edited.</param>
 /// <param name="isReadOnly">Is this data readonly?</param>
 public GenObjectViewModel(GenObject genObject, GenNamedApplicationBase definition,
                           bool isReadOnly)
 {
     IsReadOnly = isReadOnly;
     IgnorePropertyValidation = true;
     Definition    = definition;
     GenAttributes = new GenAttributes(genObject.GenDataBase.GenDataDef, genObject.ClassId)
     {
         GenObject = genObject
     };
     GenObject = genObject;
     Changed   = false;
     IsNew     = false;
 }
Пример #30
0
        private static void CreateDefinitionProperty(GenObject @class, string name, string title, string dataType,
                                                     string @default         = "", string lookupType  = "",
                                                     string lookupDependence = "", string lookupTable = "")
        {
            var property = new GenObject(@class, @class.SubClass[1], 3);

            SetAttribute(property, 0, name);
            SetAttribute(property, 1, title);
            SetAttribute(property, 2, dataType);
            SetAttribute(property, 3, @default);
            SetAttribute(property, 4, lookupType);
            SetAttribute(property, 5, lookupDependence);
            SetAttribute(property, 6, lookupTable);
            @class.SubClass[1].Add(property);
        }
Пример #31
0
        public string GetNodeExpansionText(GenDataBase genData, GenObject genObject)
        {
            GenObject = genObject;
            if (Fragment == null)
            {
                return("");
            }
            var context = GenObject.GetContext(genObject ?? genData.Root, Fragment.ClassName());

            if (context == null)
            {
                return("");
            }
            return(GenFragmentExpander.Expand(genData.GenDataDef, context, Fragment));
        }
Пример #32
0
        /// <summary>
        /// Creates a playable sound instance managed by a <c>GenSound</c> object.
        /// </summary>
        /// <param name="sound">The <c>GenSound</c> object that this sound instance is handled by.</param>
        public GenSoundInstance(GenSound sound)
        {
            _soundParent = sound;
            _sound = _soundParent.Sound;

            SoundInstance = _soundParent.Sound.CreateInstance();
            SoundInstance.IsLooped = _soundParent.IsLooped;
            SoundInstance.Volume = _soundParent.Volume;
            SoundInstance.Pitch = _soundParent.Pitch;
            SoundInstance.Pan = _soundParent.Pan;

            _fadeTimer = new GenTimer(0f, null);
            Follow = _soundParent.Follow;

            // Call UpdateSound initially to correct the volume value.
            UpdateSound();
        }
Пример #33
0
        /// <summary>
        /// Checks for overlap between the movements bounds of two objects.
        /// </summary>
        /// <param name="objectA">The first object to check for an overlap.</param>
        /// <param name="objectB">The second object to check for an overlap.</param>
        /// <param name="callback">The delegate method that will be invoked if an overlap occurs.</param>
        /// <returns>True if an overlap occurs, false if not.</returns>
        public static bool Overlap(GenObject objectA, GenObject objectB, CollideEvent callback)
        {
            // Check if both objects are alive to avoid unwanted overlap checks that may be called by a quadtree.
            if ((objectA.Exists && objectA.Active) && (objectB.Exists && objectB.Active))
            {
                if (objectA.MoveBounds.Intersects(objectB.MoveBounds))
                {
                    if (callback != null)
                    {
                        _collideEventArgs.ObjectA = objectA;
                        _collideEventArgs.ObjectB = objectB;
                        _collideEventArgs.TouchingA = GenObject.Direction.None;
                        _collideEventArgs.TouchingB = GenObject.Direction.None;

                        callback(_collideEventArgs);
                    }

                    return true;
                }
            }

            return false;
        }
Пример #34
0
        /// <summary>
        /// Make a link constraint connecting two object points.
        /// </summary>
        /// <param name="pointA">The first object to use as a connection point.</param>
        /// <param name="pointB">The second object to use as a connection point.</param>
        public void MakeLink(GenObject pointA, GenObject pointB)
        {
            Add(pointA);
            Add(pointB);

            Links.Add(new GenLink(pointA, pointB));
        }
Пример #35
0
 /// <summary>
 /// A particle emitter that emits particles from a point, 
 /// </summary>
 /// <param name="x">The x position of the top-left corner of the emitter.</param>
 /// <param name="y">The y position of the top-left corner of the emitter.</param>
 public GenEmitter(float x, float y)
 {
     _position = new Vector2(x, y);
     _bounds = new GenAABB(x, y, 0f, 0f);
     _boundingRect = Rectangle.Empty;
     MinParticleSpeedX = -100;
     MaxParticleSpeedX = 100;
     MinParticleSpeedY = -100;
     MaxParticleSpeedY = 100;
     MinRotation = 0;
     MaxRotation = 0;
     MinRotationSpeed = 0;
     MaxRotationSpeed = 0;
     Colors = new List<Color>();
     StartAlpha = 1f;
     EndAlpha = 1f;
     StartScale = 1f;
     EndScale = 1f;
     Explode = true;
     EmitQuantity = 10;
     _emitTimer = new GenTimer(0.1f, EmitParticles);
     _emitTimer.IsLooping = true;
     InheritVelocity = false;
     Parent = null;
     ParentOffset = Vector2.Zero;
 }
Пример #36
0
        /// <summary>
        /// Applies 2D positional adjustments to the sound instance using a source and receivers (cameras) of the sound.
        /// The volume, pan, and pitch values are averaged when using multiple cameras depending on their distances from the source.
        /// </summary>
        /// <param name="source">The source of the sound.</param>
        /// <param name="cameras">A list of the receivers (cameras) of the sound.</param>
        public void Apply2D(GenObject source, List<GenCamera> cameras)
        {
            if ((cameras != null) && (cameras.Count > 0))
            {
                Vector2 distance = source.CenterPosition - cameras[0].CenterPosition;

                if (cameras.Count == 1)
                {
                    float distanceFade = MathHelper.Clamp((GenSound.DistanceScale - distance.Length()) / GenSound.DistanceScale, 0f, 1f);

                    SoundInstance.Volume = ((_soundParent == null) ? _volume : _soundParent.Volume) * distanceFade;
                    SoundInstance.Pan = MathHelper.Clamp(distance.X / GenSound.DistanceScale, -1f, 1f) * -cameras[0].Up.Y;
                    SoundInstance.Pitch = GenSound.GetDopplerShift(Follow.Velocity, cameras[0].Velocity, distance, GenSound.DopplerFactor);
                }
                else
                {
                    GenCamera workingCamera = cameras[0];

                    // Get the distance from the sound source to the center of the first camera, and set it as the initial minimum distance.
                    Vector2 distanceMin = distance;
                    float distanceMinLength = distanceMin.Length();

                    // Iterate through each remaining camera, checking for the one closest to the sound source.
                    for (int i = 1; i < cameras.Count; i++)
                    {
                        Vector2 newDistance = source.CenterPosition - cameras[i].CenterPosition;
                        float newDistanceLength = newDistance.Length();

                        // If the current camera is closest to the sound source, set it as the working camera and minimum distance.
                        if (newDistanceLength < distanceMinLength)
                        {
                            workingCamera = cameras[i];
                            distanceMin = newDistance;
                            distanceMinLength = newDistanceLength;
                        }
                    }

                    float cameraFactor = 0f;
                    float cameraFactorSum = 0f;

                    Vector2 distanceSum = Vector2.Zero;
                    Vector2 velocitySum = Vector2.Zero;
                    Vector2 upSum = Vector2.Zero;

                    Vector2 cameraDistance = Vector2.Zero;

                    // Iterate through each camera, calculating their influences on the sound instance depending on their distances from the source.
                    // The closest camera will have the most influence.
                    foreach (GenCamera camera in cameras)
                    {
                        if (camera == workingCamera)
                        {
                            cameraFactorSum += 1f;

                            distanceSum += distanceMin;
                            velocitySum += workingCamera.Velocity;
                            upSum += workingCamera.Up;
                        }
                        else
                        {
                            cameraDistance = source.CenterPosition - camera.CenterPosition;
                            cameraFactor = 1f - (cameraDistance.Length() * GenSound.InverseDistanceScale);

                            if (cameraFactor > 0)
                            {
                                cameraFactorSum += cameraFactor;

                                distanceSum += cameraDistance * cameraFactor;
                                velocitySum += camera.Velocity * cameraFactor;
                                upSum += camera.Up * cameraFactor;
                            }
                        }
                    }

                    // Inverse the camera factor sum to reduce division calculations.
                    float inverseCameraFactorSum = 1f / cameraFactorSum;

                    Vector2 averageDistance = distanceSum * inverseCameraFactorSum;

                    float distanceFade = MathHelper.Clamp((GenSound.DistanceScale - distanceMin.Length()) * GenSound.InverseDistanceScale, 0f, 1f);

                    SoundInstance.Volume = ((_soundParent == null) ? _volume : _soundParent.Volume) * distanceFade;
                    SoundInstance.Pan = MathHelper.Clamp(averageDistance.X * GenSound.InverseDistanceScale, -1f, 1f) * -(upSum * inverseCameraFactorSum).Y;
                    SoundInstance.Pitch = GenSound.GetDopplerShift(Follow.Velocity, (velocitySum * inverseCameraFactorSum), averageDistance, GenSound.DopplerFactor);
                }
            }
        }
Пример #37
0
        /// <summary>
        /// Applies collision detection and response against two objects that may overlap.
        /// </summary>
        /// <param name="objectA">The first object to check for a collision.</param>
        /// <param name="objectB">The second object to check for a collision.</param>
        /// <param name="callback">The delegate method that will be invoked if a collision occurs.</param>
        /// <param name="collidableEdges">A bit field of flags determining which edges of the second object are collidable.</param>
        /// <returns>True if a collision occurs, false if not.</returns>
        public static bool Collide(GenObject objectA, GenObject objectB, CollideEvent callback, GenObject.Direction collidableEdges = GenObject.Direction.Any)
        {
            // Do not check for collisions if the objects are the same.
            if (objectA == objectB)
                return false;

            // Do not check for collisions if either object is not solid, or if both objects are immovable.
            if ((!objectA.Solid || !objectB.Solid) || (objectA.Immovable && objectB.Immovable))
                return false;

            // If the movement bounding boxes of each object are overlapping, check for a collision.
            if (Overlap(objectA, objectB, callback))
            {
                // Get the normal direction of the collision from bounding box A to B along the least penetrating axis.
                // Return no collision if the surface normal is projected towards a non-collidable edge of bounding box B.
                _distance = objectA.Bounds.GetDistanceAABB(objectB.Bounds);

                // The greatest absolute distance value between the two bounding boxes is along the axis of least penetration.
                if (_distance.X > _distance.Y)
                {
                    if (objectA.Bounds.MidpointX > objectB.Bounds.MidpointX)
                    {
                        // The collision normal is pointing from the left edge of bounding box A.
                        _collisionNormal.X = -1f;
                        _collisionNormal.Y = 0f;

                        if ((collidableEdges & GenObject.Direction.Right) == 0)
                            return false;
                    }
                    else
                    {
                        // The collision normal is pointing from the right edge of bounding box A.
                        _collisionNormal.X = 1f;
                        _collisionNormal.Y = 0f;

                        if ((collidableEdges & GenObject.Direction.Left) == 0)
                            return false;
                    }
                }
                else
                {
                    if (objectA.Bounds.MidpointY > objectB.Bounds.MidpointY)
                    {
                        // The collision normal is pointing from the top edge of bounding box A.
                        _collisionNormal.X = 0f;
                        _collisionNormal.Y = -1f;

                        if ((collidableEdges & GenObject.Direction.Down) == 0)
                            return false;
                    }
                    else
                    {
                        // The collision normal is pointing from the bottom edge of bounding box A.
                        _collisionNormal.X = 0f;
                        _collisionNormal.Y = 1f;

                        if ((collidableEdges & GenObject.Direction.Up) == 0)
                            return false;
                    }
                }

                float distance = Math.Max(_distance.X, _distance.Y);
                float remove;

                // Apply an alternative collision response against tiles for pixel-perfect accuracy.
                if (objectB is GenTile)
                {
                    // Get the amount of normal velocity to remove from the object so that it just touches along the collision surface of the tile.
                    remove = Vector2.Dot(-objectA.Velocity, _collisionNormal) + Math.Max(distance, 0f) * GenG.InverseTimeStep;

                    // If the amount of velocity to remove is positive, the object will separate itself from the tile.
                    if (remove >= 0)
                        return false;

                    if (_collisionNormal.X != 0)
                    {
                        objectA.X = (_collisionNormal.X == 1) ? objectB.X - objectA.Bounds.Width : objectB.Bounds.Right;
                        objectA.Velocity.X = 0f;
                    }
                    else
                    {
                        objectA.Y = (_collisionNormal.Y == 1) ? objectB.Y - objectA.Bounds.Height : objectB.Bounds.Bottom;
                        objectA.Velocity.Y = 0f;
                    }
                }
                else
                {
                    // Get the relative velocity along the collision normal.
                    float relativeNormalVelocity = Vector2.Dot(objectB.Velocity - objectA.Velocity, _collisionNormal);

                    // Get the amount of relative normal velocity to remove so that the bounding boxes are just touching along the collision surface.
                    remove = relativeNormalVelocity + distance * GenG.InverseTimeStep;

                    // If the amount of velocity to remove is positive, the objects will separate themselves.
                    if (remove >= 0)
                        return false;

                    float impulse = remove / (objectA.InverseMass + objectB.InverseMass);

                    if (!objectA.Immovable)
                        objectA.Velocity += impulse * _collisionNormal * objectA.InverseMass;

                    if (!objectB.Immovable)
                        objectB.Velocity -= impulse * _collisionNormal * objectB.InverseMass;
                }

                // Use a bit field of flags to provide the direction that each object is colliding in during the current collision.
                GenObject.Direction touchingA = GenObject.Direction.None;
                GenObject.Direction touchingB = GenObject.Direction.None;

                if (_collisionNormal.X != 0)
                {
                    if (_collisionNormal.X == 1)
                    {
                        objectA.Touching |= GenObject.Direction.Right;
                        objectB.Touching |= GenObject.Direction.Left;

                        touchingA |= GenObject.Direction.Right;
                        touchingB |= GenObject.Direction.Left;
                    }
                    else
                    {
                        objectA.Touching |= GenObject.Direction.Left;
                        objectB.Touching |= GenObject.Direction.Right;

                        touchingA |= GenObject.Direction.Left;
                        touchingB |= GenObject.Direction.Right;
                    }
                }
                else
                {
                    if (_collisionNormal.Y == 1)
                    {
                        objectA.Touching |= GenObject.Direction.Down;
                        objectB.Touching |= GenObject.Direction.Up;

                        touchingA |= GenObject.Direction.Down;
                        touchingB |= GenObject.Direction.Up;

                        if (objectB.IsPlatform)
                        {
                            if (objectA.Acceleration.X == 0)
                                objectA.Platform = objectB;
                        }
                    }
                    else
                    {
                        objectA.Touching |= GenObject.Direction.Up;
                        objectB.Touching |= GenObject.Direction.Down;

                        touchingA |= GenObject.Direction.Up;
                        touchingB |= GenObject.Direction.Down;

                        if (objectA.IsPlatform)
                        {
                            if (objectB.Acceleration.X == 0)
                                objectB.Platform = objectA;
                        }
                    }
                }

                if (callback != null)
                {
                    _collideEventArgs.ObjectA = objectA;
                    _collideEventArgs.ObjectB = objectB;
                    _collideEventArgs.TouchingA = touchingA;
                    _collideEventArgs.TouchingB = touchingB;

                    callback(_collideEventArgs);
                }

                return true;
            }

            return false;
        }