Example #1
0
        public bool Pointcast(Vector3 point)
        {
            var jPoint = point.ToJVector();

            return(GJKCollide.Pointcast(this.body.Shape, ref this.body.orientation, ref this.body.position, ref jPoint));
        }
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            KeyboardState keys             = Keyboard.GetState();
            JVector       moveVector       = JVector.Zero;
            float         amountOfMovement = 0.05f;

            if (keys.IsKeyDown(Keys.Right))
            {
                moveVector.X += amountOfMovement;
            }
            if (keys.IsKeyDown(Keys.Left))
            {
                moveVector.X -= amountOfMovement;
            }
            if (keys.IsKeyDown(Keys.Down))
            {
                moveVector.Y -= amountOfMovement;
            }
            if (keys.IsKeyDown(Keys.Up))
            {
                moveVector.Y += amountOfMovement;
            }

            body1.Position += moveVector;

            if (keys.IsKeyDown(Keys.OemPlus) && oldState.IsKeyUp(Keys.OemPlus))
            {
                GJKCollide.MaxIterations++;
            }
            if (keys.IsKeyDown(Keys.OemMinus) && oldState.IsKeyUp(Keys.OemMinus))
            {
                GJKCollide.MaxIterations--;
            }

            GJKCollide.MaxIterations = (int)JMath.Clamp(GJKCollide.MaxIterations, 0, 25);

            bool changeShape = false;

            if (keys.IsKeyDown(Keys.D1) && oldState.IsKeyUp(Keys.D1))
            {
                shapeType++;
                changeShape = true;
            }
            if (keys.IsKeyDown(Keys.D2) && oldState.IsKeyUp(Keys.D2))
            {
                shapeType--;
                changeShape = true;
            }

            shapeType = (int)JMath.Clamp(shapeType, 0, 2);
            if (changeShape)
            {
                Random r = new Random();
                switch (shapeType)
                {
                case 0:         // circle
                    body1 = new RigidBody(new CircleShape((float)r.NextDouble() * 3f));
                    break;

                case 1:          // capsule
                    body1 = new RigidBody(new CapsuleShape((float)r.NextDouble() * 3f, (float)r.NextDouble() * 1f));
                    break;

                case 2:         // box
                    body1 = new RigidBody(new BoxShape((float)r.NextDouble() * 3f, (float)r.NextDouble() * 3f));
                    break;
                }
            }


            body1.Orientation += 0.005f;
            body2.Orientation -= 0.005f;

            JMatrix o1   = JMatrix.CreateRotationZ(body1.Orientation);
            JMatrix o2   = JMatrix.CreateRotationZ(body2.Orientation);
            JVector pos1 = body1.Position;
            JVector pos2 = body2.Position;

            JVector point2;

            sw.Start();
            hit = GJKCollide.ClosestPoints(body1.Shape, body2.Shape, ref o1, ref o2, ref pos1, ref pos2, out point, out point2, out normal);
            sw.Stop();

            penetration = JVector.Distance(point, point2);

            ticks = sw.ElapsedTicks;
            sw.Reset();

            DebugDrawer.DrawPoint(point2);
            DebugDrawer.DrawPoint(point);
            DebugDrawer.Color = Color.Red;

            DebugDrawer.DrawLine(JVector.Zero, normal);

            DebugDrawer.Color = Color.Black;
            DebugDrawer.DrawLine(JVector.Up, JVector.Down);
            DebugDrawer.DrawLine(JVector.Left, JVector.Right);

            body1.DebugDraw(DebugDrawer);
            body2.DebugDraw(DebugDrawer);

            oldState = keys;

            base.Update(gameTime);
        }
Example #3
0
        /// <summary>
        /// Adds a body to the fluid. Only bodies which where added
        /// to the fluidvolume gets affected by buoyancy forces.
        /// </summary>
        /// <param name="body">The body which should be added.</param>
        /// <param name="subdivisions">The object is subdivided in smaller objects
        /// for which buoyancy force is calculated. The more subdivisons the better
        /// the results. Note that the total number of subdivisions is subdivisions³.</param>
        public void Add(RigidBody body, int subdivisions)
        {
            List <JVector> massPoints = new List <JVector>();
            JVector        testVector;

            JVector diff = body.Shape.BoundingBox.Max - body.Shape.BoundingBox.Min;

            if (diff.IsNearlyZero())
            {
                throw new InvalidOperationException("BoundingBox volume of the shape is zero.");
            }

            Multishape ms     = body.Shape as Multishape;
            int        values = 0;

            if (ms != null)
            {
                JBBox largeBox = JBBox.LargeBox;
                values = ms.Prepare(ref largeBox);
            }

            for (int i = 0; i < subdivisions; i++)
            {
                for (int e = 0; e < subdivisions; e++)
                {
                    for (int k = 0; k < subdivisions; k++)
                    {
                        testVector.X = body.Shape.BoundingBox.Min.X + (diff.X / (float)(subdivisions - 1)) * ((float)i);
                        testVector.Y = body.Shape.BoundingBox.Min.Y + (diff.Y / (float)(subdivisions - 1)) * ((float)e);
                        testVector.Z = body.Shape.BoundingBox.Min.Z + (diff.Z / (float)(subdivisions - 1)) * ((float)k);

                        JMatrix ident = JMatrix.Identity;
                        JVector zero  = JVector.Zero;

                        if (ms != null)
                        {
                            for (int j = 0; j < values; j++)
                            {
                                ms.SetCurrentShape(j);


                                if (GJKCollide.Pointcast(body.Shape, ref ident,
                                                         ref zero, ref testVector))
                                {
                                    massPoints.Add(testVector);
                                }
                            }
                        }
                        else
                        {
                            if (GJKCollide.Pointcast(body.Shape, ref ident,
                                                     ref zero, ref testVector))
                            {
                                massPoints.Add(testVector);
                            }
                        }
                    }
                }
            }

            samples.Add(body.Shape, massPoints.ToArray());
            bodies.Add(body);
        }
        //int sampleCount = 50;
        //float distance = 4.0f;
        public void UpdateAmbientOcclusion(Model model, Group occluders, string mapName)
        {
#if false // \todo fix
            GeometryMesh mesh = model.Batch.MeshSource as GeometryMesh;
            if (mesh == null)
            {
                return;
            }
            Geometry geometry = mesh.Geometry;

            model.UpdateOctree();
            var shape = new TriangleMeshShape(model.Octree);
            shape.SphericalExpansion = 0.0f;

#if VISUALIZE_RAYS
            sceneManager.DebugLineRenderer.Begin();
#endif

            var pointLocations   = geometry.PointAttributes.Find <Vector3>("point_locations");
            var polygonCentroids = geometry.PolygonAttributes.Find <Vector3>("polygon_centroids");
            var pointNormals     = geometry.PointAttributes.Find <Vector3>(mapName);
            var cornerNormals    = geometry.CornerAttributes.Contains <Vector3>("corner_normals") ? geometry.CornerAttributes.Find <Vector3>("corner_normals") : null;
            var cornerColors     = geometry.CornerAttributes.FindOrCreate <Vector4>("corner_colors");
            cornerColors.Clear();
            int badCount = 0;
            foreach (Polygon polygon in geometry.Polygons)
            {
                foreach (Corner corner in polygon.Corners)
                {
                    Point point = corner.Point;

                    //  Start from corner position slightly moved towards polygon center
                    Vector3 initialEye = Vector3.Mix(pointLocations[point], polygonCentroids[polygon], 0.001f);
                    Vector3 normal;

                    if (
                        (cornerNormals != null) &&
                        (cornerNormals.ContainsKey(corner) == true)
                        )
                    {
                        normal = cornerNormals[corner];
                    }
                    else
                    {
                        normal = pointNormals[point];
                    }

                    JMatrix orientation    = JMatrix.Identity;
                    JMatrix invOrientation = JMatrix.Identity;
                    Vector3 modelPosition  = Vector3.Zero;

                    //  Slightly up from surface
                    initialEye += normal * 0.01f;

                    int visibility = sampleCount;

                    JVector position = Conversions.JVector(modelPosition);
                    JVector direction;
                    JVector jnormal;

                    Vector3 eye    = initialEye;
                    JVector origin = Conversions.JVector(eye);

                    //  Sample a few directions
                    for (int c = 0; c < sampleCount; ++c)
                    {
                        //  Get a random direction until it points up from the surface
                        Vector3 sampleDirection;
                        float   dot;
                        do
                        {
                            sampleDirection = Random();
                            dot             = Vector3.Dot(normal, sampleDirection);
                        }while(dot < 0.25f);

                        //  Scale
                        direction = Conversions.JVector(sampleDirection * distance);

                        bool hit = false;
                        {
                            float tempFraction;

                            if (shape is Multishape)
                            {
                                Multishape ms = (shape as Multishape).RequestWorkingClone();
                                JVector    tempNormal;
                                int        msLength = ms.Prepare(ref origin, ref direction);

                                for (int i = 0; i < msLength; i++)
                                {
                                    ms.SetCurrentShape(i);

                                    if (
                                        GJKCollide.Raycast(
                                            ms, ref orientation, ref invOrientation, ref position,
                                            ref origin, ref direction, out tempFraction, out tempNormal
                                            )
                                        )
                                    {
                                        hit = true;
                                        break;
                                    }
                                }

                                ms.ReturnWorkingClone();
                            }
                            else
                            {
                                hit = GJKCollide.Raycast(
                                    shape, ref orientation, ref invOrientation, ref position,
                                    ref origin, ref direction, out tempFraction, out jnormal
                                    );
                            }
                        }


                        if (hit)
                        {
                            visibility -= 1;
                        }

                        Vector3 root = new Vector3(origin.X, origin.Y, origin.Z);
                        Vector3 tip  = root + 0.02f * new Vector3(direction.X, direction.Y, direction.Z);
#if VISUALIZE_RAYS
                        sceneManager.DebugLineRenderer.Line(
                            root,
                            Vector4.Zero,
                            tip,
                            (hit ? Vector4.UnitX : Vector4.UnitY)
                            );
#endif
                    }
                    float visibilityFloat = (float)(visibility) / (float)(sampleCount);
                    cornerColors[corner] = new Vector4(visibilityFloat, visibilityFloat, visibilityFloat, 1.0f);
                }
            }
            mesh.Geometry.ComputePolygonCentroids();
            mesh.Geometry.ComputePolygonNormals();
            mesh.Geometry.SmoothNormalize("corner_normals", "polygon_normals", (2.0f * (float)Math.PI));
            mesh.Geometry.SmoothAverage("corner_colors", mapName);
            mesh.BuildMeshFromGeometry(BufferUsageHint.StaticDraw, NormalStyle.CornerNormals);
            //UpdateMeshCornerColors(mesh);
            Debug.WriteLine("bad count = " + badCount.ToString());

#if VISUALIZE_RAYS
            sceneManager.DebugLineRenderer.End();
            sceneManager.DebugFrame = model.Frame;
#endif

            //model.Name = "AmbientOcclusion(" + model.Name + ")";
#endif
        }