Exemple #1
0
        private void MoveToObject(StreamWriter stream,
                                  CollisionAPI API, CollisionShape collisionShape,
                                  CollisionShape movingShape)
        {
            stream.Write("\n\n\nEntering MoveToObject\n");
            // Create a MovingObject, and add movingShape to it
            MovingObject mo = new MovingObject();

            API.AddPartToMovingObject(mo, movingShape);

            // Move movingObject 1 foot at a time toward the sphere
            Vector3 toShape = collisionShape.center - movingShape.center;

            stream.Write(string.Format("movingShape {0}\n", movingShape.ToString()));
            stream.Write(string.Format("collisionShape {0}\nDisplacement Vector {1}\n",
                                       collisionShape.ToString(), toShape.ToString()));
            // We'll certainly get there before steps expires
            int steps = (int)Math.Ceiling(toShape.Length);
            // 1 foot step in the right direction
            Vector3 stepVector = toShape.ToNormalized();

            stream.Write(string.Format("Steps {0}, stepVector {1}\n", steps, stepVector.ToString()));
            bool hitIt = false;
            // Loop til we smack into something
            CollisionParms parms = new CollisionParms();

            for (int i = 0; i < steps; i++)
            {
                // Move 1 foot; if returns true, we hit something
                hitIt = (API.TestCollision(mo, stepVector, parms));
                stream.Write(string.Format("i = {0}, hitIt = {1}, movingShape.center = {2}\n",
                                           i, hitIt, movingShape.center.ToString()));
                if (hitIt)
                {
                    stream.Write(string.Format("collidingPart {0}\nblockingObstacle {1}\n, normPart {2}, normObstacle {3}\n",
                                               parms.part.ToString(), parms.obstacle.ToString(),
                                               parms.normPart.ToString(), parms.normObstacle.ToString()));
                    return;
                }
                stream.Write("\n");
            }
            Debug.Assert(hitIt, "Didn't hit the obstacle");
        }
Exemple #2
0
        // Move the desired displacement, limited by hitting an
        // obstacle.  Then, if we're not already at the terrain level,
        // "fall" until we are either at the terrain level, or hit an
        // obstacle
        public static Vector3 MoveMobNode(MobNode mobNode, Vector3 requestedDisplacement, Client client)
        {
//             Logger.Log(0, "MoveMobNode oid {0} requestedDisplacement {1}", mobNode.Oid, requestedDisplacement);
//             log.DebugFormat("MoveMobNode: mobNode oid {0}, name {1}, followTerrain {2}, position {3}, disp {4}",
//                             mobNode.Oid, mobNode.Name, mobNode.FollowTerrain, mobNode.Position, requestedDisplacement);
            Vector3      start    = mobNode.Position;
            MovingObject mo       = mobNode.Collider;
            bool         collided = false;
            // Zero the y coordinate of displacement, because it seems
            // that it can be arbitrarily large
            Vector3 desiredDisplacement = requestedDisplacement;

            if (mobNode.FollowTerrain)
            {
                desiredDisplacement.y = 0;
            }
            if (desiredDisplacement.LengthSquared <= float.Epsilon)
            {
                return(start);
            }
            if (MO.DoLog)
            {
                MO.Log("MoveMobNode called with mobNode {0} at {1}, disp of {2}",
                       mobNode.Oid, start, requestedDisplacement);
            }
            if (collisionManager == null)
            {
                log.Info("MoveMobNode: returning because collisionManager isn't initialized");
                return(start + desiredDisplacement);
            }
            if (mo == null || mo.parts.Count == 0)
            {
                if (MO.DoLog)
                {
                    MO.Log("MoveMobNode returning because no collision volume for node");
                }
                return(start + requestedDisplacement);
            }
            if (mobNode is Player && NowColliding(mo, "Testing player collision on entry"))
            {
                if (client.MillisecondsStuckBeforeGotoStuck != 0)
                {
                    if (!playerStuck)
                    {
                        stuckGotoTime = DateTime.Now.AddMilliseconds(client.MillisecondsStuckBeforeGotoStuck);
                        playerStuck   = true;
                    }
                    else if (DateTime.Now >= stuckGotoTime)
                    {
                        // We issue the goto command to move us out of the
                        // collision volume
                        client.Write("Executing /stuck command because player has been in a collision volume for " + client.MillisecondsStuckBeforeGotoStuck + " milliseconds");
                        client.NetworkHelper.SendTargettedCommand(client.Player.Oid, "/stuck");
                        playerStuck = false;
                        return(start);
                    }
                }
            }
            else
            {
                playerStuck = false;
            }
            // If we haven't completed setup to this extent, just give up
            CollisionParms parms = new CollisionParms();
            Vector3        pos   = FindMobNodeDisplacement(mobNode, parms, desiredDisplacement, out collided);
//             log.DebugFormat("MoveMobNode: mobNode oid {0}, name {1}, mob node position {2}, displacement {3}",
//                 mobNode.Oid, mobNode.Name, pos, requestedDisplacement);
            float h = worldManager.GetHeightAt(pos);

            // If we're already below ground level, just set our
            // level to ground level.  This will have to be modified
            // if we deal with caves
            if (pos.y - h < 0)
            {
//                 log.DebugFormat("MoveMobNode: mobNode oid {0}, name {1} below terrain level", mobNode.Oid, mobNode.Name);
                mo.AddDisplacement(new Vector3(0f, h - pos.y, 0f));
                pos.y = h;
                if (MO.DoLog && (pos.y - h) < -.001 * Client.OneMeter)
                {
                    MO.Log(string.Format(" MobNode at {0} is below ground height {1}!",
                                         pos, h));
                }
            } // else {
            if (mobNode.FollowTerrain)
            {
//                  NowColliding(mo, " Before falling loop");
                // Fall toward the terrain or an obstacle, whichever comes
                // first
                float step = mo.StepSize(new Vector3(0, h, 0));
                while (true)
                {
                    if (Math.Abs(pos.y - h) < CollisionAPI.VerticalTerrainThreshold * Client.OneMeter)
                    {
                        mo.AddDisplacement(new Vector3(0f, h - pos.y, 0f));
                        pos.y = h;
                        break;
                    }
                    else
                    {
                        float   dy           = -Math.Min(pos.y - h, step);
                        Vector3 displacement = new Vector3(0, dy, 0);
                        Vector3 cd           = displacement;
                        if (MO.DoLog)
                        {
                            MO.Log(" Testing for collision falling {0}", dy);
                            TraceMOBottom(mo, " Before falling");
                        }
                        if (collisionManager.TestCollision(mo, ref displacement, parms))
                        {
                            if (MO.DoLog)
                            {
                                TraceMOBottom(mo, " After TestCollision after falling");
                                NowColliding(mo, " After TestCollision after falling");
                                MO.Log(" Collision when object {0} falls from {1} to {2}",
                                       parms.part.handle, pos, pos + cd);
                                TraceObstacle(parms.obstacle);
                                MO.Log(" Adding dy {0} - displacement.y {1} to pos {2}",
                                       dy, displacement.y, pos);
                            }
                            pos.y += dy - displacement.y;
                            break;
                        }
                        if (MO.DoLog)
                        {
                            MO.Log(" Didn't collide falling; dy {0}, pos {1}",
                                   dy, pos);
                        }
                        pos.y += dy;
                    }
                }
            }
            else
            {
                if (MO.DoLog)
                {
                    MO.Log(" Not falling because mobNode {0} doesn't have FollowTerrain",
                           mobNode.Oid);
                }
            }
//          }

            if (MO.DoLog)
            {
                NowColliding(mo, " Leaving MoveMobNode");
                MO.Log("MoveMobNode returning pos {0}", pos);
                MO.Log("");
            }
            if (collided)
            {
                log.DebugFormat("MoveMobNode collided: mobNode oid {0}, name {1}, orig pos {2}, displacement {3}, new pos {4}",
                                mobNode.Oid, mobNode.Name, start, requestedDisplacement, pos);
            }
            else
            {
                log.DebugFormat("MoveMobNode didn't collide: mobNode oid {0}, name {1}, orig pos {2}, displacement {3}, new pos {4}",
                                mobNode.Oid, mobNode.Name, start, requestedDisplacement, pos);
            }
            return(pos);
        }