コード例 #1
0
        //Used by the two constructors.

        protected void _fixConvex()
        {
            // I rewrote this to make it efficient for a linked list
            // First, test a bunch using a foreach -- JC
            bool     first  = true;
            bool     second = true;
            cVector3 v1     = new cVector3();
            cVector3 v2     = new cVector3();
            float    test;

            foreach (cVector3 v3 in _vectorvert)
            {
                if (!first && !second)
                {
                    test = ((v2 - v1).mult((v3 - v1))).Z;

                    /* Take the cross product and look at the z component.
                     * If it is positive, the cross product points up, so this is
                     * counterclockwise rotation and you aren't convex. */
                    if (test < 0)
                    {
                        _convex = false;
                        break;
                    }
                    v1.copy(v2);
                    v2.copy(v3);
                }
                else if (first)
                {
                    v1.copy(v3);
                    first = false;
                }
                else // second
                {
                    v2.copy(v3);
                    second = false;
                }
            }

            // finally, do two special tests -- JC
            cVector3 last = _vectorvert[0];

            test = ((v2 - v1).mult((last - v1))).Z;
            if (test < 0)
            {
                _convex = false;
                return;
            }

            v1.copy(v2);
            v2.copy(last);
            last = _vectorvert[1];
            test = ((v2 - v1).mult((last - v1))).Z;
            if (test < 0)
            {
                _convex = false;
            }
        }
コード例 #2
0
        protected float _realdotradiusweight; //Ratio of vertex marker dot size to _Shaperadius.

        /*	DON'T put in a Real _radius or Real _angle!  C++ will let you do
         * this even though these fields exist in cSprite, but what a mistake.  If you
         * put a second _radius in here, then the cShape methods change the
         * cShape _radius, but the cSprite::radius() accessor returns the cSprite
         * _radius, which will still be 0.0 */
        //Private helper functions

        protected void _initializer() //used by the constructors
        {
            //The two CArrays are set to size 0 by their default constructors
            //Nine decoration fields
            _dotted                   = false;
            _pdotcolorstyle           = new cColorStyle();
            _pdotcolorstyle.FillColor = Color.Yellow;
            _realdotradiusweight      = 0.05f;
            // helper fields
            _convex     = true;
            _vectorvert = new LinkedList <cVector3>(
                delegate(out cVector3 v1, cVector3 v2)
            {
                v1 = new cVector3();
                v1.copy(v2);
            }
                );
            _transformedvert = new LinkedList <cVector3>(
                delegate(out cVector3 v1, cVector3 v2)
            {
                v1 = new cVector3();
                v1.copy(v2);
            }
                );
        }
コード例 #3
0
 public cForceVortex(float friction, float spiralangle, cVector3 eyeposition)
     : base(friction)
 {
     _eyeposition = new cVector3();
     _spiralangle = spiralangle;
     _eyeposition.copy(eyeposition);
 }
コード例 #4
0
        public override int clamp(cRealBox3 border)
        { /* We don't change _pskeleton as it has the geometric info.  We
           *    just change _position. */
            if (_baseAccessControl == 1)
            {
                return(base.clamp(border));
            }
            cRealBox3 effectivebox = border;
            cVector3  oldcorner;
            cVector3  newcorner    = new cVector3();
            int       outcode      = 0;
            int       totaloutcode = 0;

            for (int i = 0; i < 8; i++) //Step through the wall's corners
            {
                oldcorner = _pskeleton.corner(i) + _position;
                newcorner.copy(oldcorner);
                outcode = effectivebox.clamp(newcorner);
                if (outcode != cRealBox3.BOX_INSIDE) //corner was moved
                {
                    _position += newcorner - oldcorner;

                    /* As long at the wall is small enough to
                     * fit inside the border, the successive
                     * corrections won't cancel each other out. */
                    totaloutcode |= outcode;
                }
            }
            _wrapposition1.copy(_position);
            _wrapposition2.copy(_position);
            _wrapposition3.copy(_position);
            /* So it won't think it wrapped. */
            return(outcode);
        }
コード例 #5
0
        public override void copy(cForce pforce)
        {
            base.copy(pforce);
            if (!(pforce is cForceVortex))
            {
                return;
            }
            cForceVortex pforcechild = ( cForceVortex )(pforce);               // Cast so next lines work.

            _eyeposition.copy(pforcechild._eyeposition);
            _spiralangle = pforcechild._spiralangle;
        }
コード例 #6
0
        public override void copy(cForce pforce)
        {
            base.copy(pforce);
            if (!pforce.IsKindOf("KnockbackForce"))
            {
                return;
            }
            KnockbackForce pforcechild = (KnockbackForce)pforce;

            //copy fields here
            forceVector.copy(pforcechild.forceVector);
            count = pforcechild.count;
        }
コード例 #7
0
        public override cVector3 force(cCritter pcritter)
        {
            if (_pnode == null)
            {
                return(new cVector3(0.0f, 0.0f, 0.0f));
            }
            cVector3 pursueforcevector =
                (pcritter.directionTo(_pnode) * pcritter.MaxSpeed) - pcritter.Velocity;

            pursueforcevector.Magnitude = _intensity;
            pursueforcevector          *= pcritter.Mass;
            cVector3 p = new cVector3();

            p.copy(pursueforcevector);
            return(p);
        }
コード例 #8
0
        public override cVector3 force(cCritter pcritter)
        {
            if (_pnode == null)
            {
                return(new cVector3(0.0f, 0.0f, 0.0f));
            }
            cVector3 pursueforcevector =
                (pcritter.directionTo(_pnode).mult(pcritter.MaxSpeed)).sub(pcritter.Velocity);

            pursueforcevector.Magnitude = _intensity + 2; //increase the intensity, stronger the 'seek' force
            pursueforcevector.multassign(pcritter.Mass);
            cVector3 p = new cVector3();

            p.copy(pursueforcevector);
            return(p);
        }
コード例 #9
0
        public override cVector3 force(cCritter pcritter)
        {
            count++;

            //if the count length hasn't yet been reached, just return the upward force
            if (count != COUNT_LENGTH)
            {
                cVector3 frc = new cVector3();
                frc.copy(forceVector);
                return(frc);
            }
            //once the count length is reached, remove the upward force by setting forceVector to the zero vector.
            //TODO: remove the force from the list altogether.
            else
            {
                forceVector = new cVector3(0, 0, 0);
                cVector3 v = new cVector3();
                v.copy(forceVector);
                return(v);
            }
        }
コード例 #10
0
        public void setViewpoint(cVector3 toViewer, cVector3 lookatPoint,
                                 bool trytoseewholeworld = true)
        {
            //First do some default setup stuff
            cVector3 toviewer = new cVector3();

            toviewer.copy(toViewer);
            cVector3 lookatpoint = new cVector3();

            lookatpoint.copy(lookatPoint);
            _fieldofviewangle = cCritterViewer.STARTFIELDOFVIEWANGLE;
            Speed             = 0.0f;
            _attitude         = new cMatrix3(new cVector3(0.0f, 0.0f, -1.0f),
                                             new cVector3(-1.0f, 0.0f, 0.0f), new cVector3(0.0f, 1.0f, 0.0f),
                                             new cVector3(0.0f, 0.0f, 0.0f));

            /* To get a reasonable default orientation, we arrange the viewer axes so that:
             * viewer x axis = world -z axis, viewer y axis = world -x axis, viewer z axis = world y axis.
             * We pick this orientation so that if the viewer moves "forward" (along its tangent vector)
             * it moves towards the world.  (We correct the mismatch between the coordinate systems in the
             * cCritterViewer.loadViewMatrix method, which has a long comment about this.)
             * Note that we will adjust _position (fourth column) later in this  call
             * with a moveTo, also we may rotate the _attitude a bit. */
            if (!_perspective)                                                                        //Ortho view, simply move up.
            {
                _proportionofworldtoshow = 1.0f;                                                      //Show all of a flat world.
                moveTo(lookatpoint + (new cVector3(0.0f, 0.0f, 1.0f)) * cCritterViewer.ORTHOZOFFSET); // Get above the world
                _maxspeed = _maxspeedstandard = 0.5f * cCritterViewer.ORTHOZOFFSET;                   //Mimic perspective case.
            }
            else //_perspective
            {
                if (toviewer.IsPracticallyZero)                    //Not usable, so pick a real direction.
                {
                    toviewer.copy(new cVector3(0.0f, 0.0f, 1.0f)); //Default is straight up.
                }
                if (trytoseewholeworld)                            /* Treat toviewer as a direction, and back off in that direction
                                                                    * enough to see the whole world */
                {
                    toviewer.normalize();                          //Make it a unit vector.
                    _proportionofworldtoshow = cCritterViewer.PROPORTIONOFWORLDTOSHOW;
                    //Trying to show all of a world when flying around it, often leaves too big a space around it.
                    float furthestcornerdistance = Game.Border.maxDistanceToCorner(lookatpoint);
                    float tanangle = (float)Math.Tan(_fieldofviewangle / 2.0f); /* We work with half the fov in this calculation,
                                                                                *  the tanangle will be the ratio of visible distance to distance above the world,
                                                                                *  that is, tanangle = dr/dz, where
                                                                                *  Our dr is _proportionofworldtoshow * furthestcornerdistance, and
                                                                                *  our dz is the unknown seeallz height we need to back off to.
                                                                                *  Swap tangangle and dz to get the next formula. */
                    float seeallz  = _proportionofworldtoshow * furthestcornerdistance / tanangle;
                    moveTo(lookatpoint + toviewer * seeallz);
                }
                else /*Not trytoseewholeworld.  In this case we don't normalize toviewer, instead
                      *         we treat it as a displacment from the lookatpoint. */
                {
                    moveTo(lookatpoint + toviewer);
                }
                lookAt(lookatpoint);
                _maxspeed = _maxspeedstandard = 0.5f * (Position - lookatpoint).Magnitude;

                /* Define the speed like this so it typically takes two seconds (1/0.5)
                 * to fly in to lookatpoint. */
                _lastgoodplayeroffset = Position - Game.Player.Position;
            }
        }
コード例 #11
0
        /* Overload this so as not to change
         *  velocity as I normally want my walls to be stable and not drift after being dragged. */

        /// <summary>
        /// There's a collision if pcritter has crossed the wall or if the radius of pcritter is more than
        /// the pcritter's distance to the wall.  Has code to prevent the pcritter from going through the wall.
        /// Returns true if a collision was detected and false otherwise.
        /// </summary>
        /// <param name="pcritter">The critter to test for a collision with the wall.</param>
        /// <returns></returns>
        public override bool collide(cCritter pcritter)
        {
            cVector3 oldlocalpos, newlocalpos;
            float    newdistance;
            int      oldoutcode, newoutcode;
            bool     crossedwall;

            oldlocalpos = globalToLocalPosition(pcritter.OldPosition);
            oldoutcode  = _pskeleton.outcode(oldlocalpos);
            newlocalpos = globalToLocalPosition(pcritter.Position);
            newdistance = _pskeleton.distanceToOutcode(newlocalpos,
                                                       out newoutcode); //Sets the newoutcode as well.
            crossedwall = crossed(oldoutcode, newoutcode);

            if (newdistance >= pcritter.Radius && !crossedwall) //No collision
            {
                return(false);                                  /*See if there's a collision at all. We
                                                                 * say there's a collision if crossedwall or if the
                                                                 * cCritterWall.distance is less than radius.  Remember that
                                                                 * cCritterWall.distance measures the distance to the OUTSIDE
                                                                 * PERIMETER of the box, not the distance to the box's center. */
            }

            /* I collided, so I need to move back further into the last good
             * zone I was in outside the wall.  I want to set newlocalpos so
             * the rim of its critter is touching the wall. The idea is to back
             * up in the direction of oldlocalpos.  To allow the possibility
             * of skidding along the wall, we plan to back up from the
             * the face (or edge or corner) facing oldlocalpos.  This works
             * only if oldlocalpos was a good one, not inside the box.  In
             * principle this should always be true, but some rare weird circumstance
             * (like a triple collsion) might mess this up, so we check for the
             * bad case before starting. */

            if (oldoutcode == cRealBox3.BOX_INSIDE) //Note that this almost never happens.
            {
                cVector3 insidepos = new cVector3();
                insidepos.copy(oldlocalpos);
                oldlocalpos -= pcritter.Tangent * _pskeleton.MaxSize;
                //Do a brutally large backup to get out of the box for sure.
                oldoutcode = _pskeleton.outcode(oldlocalpos);
                //Recalculate outcode at this new position.
                oldlocalpos = _pskeleton.closestSurfacePoint(oldlocalpos, oldoutcode,
                                                             insidepos, cRealBox3.BOX_INSIDE, false);
                //Go to the closest surface point from there.
                oldoutcode = _pskeleton.outcode(oldlocalpos);
                //Recalculate outcode one more time to be safe.
                crossedwall = crossed(oldoutcode, newoutcode);
                //Recalculate crossedwall
            }

            /* I find that with this code, the mouse can drag things through walls,
             * so I do a kludge to block it by setting crossedwall to TRUE, this
             * affects the action of cRealBox.closestSurfacePoint, as modified
             * in build 34_4. */
            if (pcritter.Listener is cListenerCursor)
            {
                crossedwall = true; //Don't trust the mouse listener.
            }
            newlocalpos = _pskeleton.closestSurfacePoint(oldlocalpos, oldoutcode,
                                                         newlocalpos, newoutcode, crossedwall);

            /* This call to closestSurfacePoint will move the newlocal pos
             * from the far new side (or inside, or overlapping) of the box back to
             * the surface, usually on the old near side, edge, or corner given by
             * oldoutcode. This prevents going through the	wall.
             * If oldoutcode is a corner position and you are in fact heading
             * towards a face near the corner, we used to bounce off the corner
             * even though visually you can see you should bounce off the
             * face.  This had the effect of making a scooter player get hung up on
             * a corner sometimes. As of build 34_3, I'm moving the
             * newlocalpos to the newoutocode side in the case where oldlocalpos
             * is an edge or a corner, and where crossedwall isn't TRUE.  I
             * have to force in a TRUE for the cCursorLIstener case.  The USEJIGGLE
             * code below also helps keep non-player critters from getting stuck
             * on corners. */
            //Now back away from the box.
            newoutcode = _pskeleton.outcode(newlocalpos);
            cVector3 avoidbox = _pskeleton.escapeVector(newlocalpos, newoutcode);

            newlocalpos += avoidbox * pcritter.Radius;
            newoutcode   = _pskeleton.outcode(newlocalpos);
            pcritter.moveTo(localToGlobalPosition(newlocalpos), true);
            //TRUE means continuous motion, means adjust tangent etc.
            //Done with position, now change the velocity
            cVector3 localvelocity    = globalToLocalDirection(pcritter.Velocity);
            cVector3 oldlocalvelocity = new cVector3();

            oldlocalvelocity.copy(localvelocity);
            _pskeleton.reflect(localvelocity, newoutcode);

            /* I rewrote the reflect code on Feb 22, 2004 for VErsion 34_3, changing
             * it so that when you reflect off an edge or corner, you only bounce
             * the smallest of your three velocity components. Balls stll seem to
             * get hung up on the corner once is awhile. */
            /* Now decide, depending on the pcritter's absorberflag and bounciness,
             * how much you want to use the new localvelocity vs. the
             * oldlocalvelocity. We decompose the new localvelocity into the
             * tangentvelocity parallel to the wall and the normalvelocity
             * away from the wall. Some pencil and paper drawings convince
             * me that the tangent is half the sum of the oldlocalvelocity
             * and the reflected new localvelocity. */
            cVector3 tangentvelocity = (localvelocity + oldlocalvelocity) * 0.5f;
            cVector3 normalvelocity  = localvelocity - tangentvelocity;
            float    bouncefactor    = 1.0f;

            if (pcritter.AbsorberFlag)
            {
                bouncefactor = 0.0f;
            }
            else
            {
                bouncefactor = pcritter.Bounciness;
            }
            localvelocity = tangentvelocity + normalvelocity * bouncefactor;

            /* Maybe the rotation should depend on the kind of edge or corner.
             * Right now let's just use critter's binormal. Don't to it
             * to the player or viewer as it's confusing.  */
            if (!(cRealBox3.isFaceOutcode(newoutcode)) && //edge or corner
                !(pcritter is cCritterViewer) &&          //not viewer
                !(pcritter is cCritterArmedPlayer))
            //Not player.  Note that cPlayer inherits from cCritterArmedPlayer,
            //so don't use cCritterPlayer as the base class here.
            {
                localvelocity.rotate(new cSpin(
                                         Framework.randomOb.randomReal(
                                             -cCritterWall.CORNERJIGGLETURN,
                                             cCritterWall.CORNERJIGGLETURN), //A random turn
                                         pcritter.Binormal));                //Around the critter's binormal
                localvelocity *= cCritterWall.CORNERJIGGLEKICK;              //Goose it a little
            }
            pcritter.Velocity = localToGlobalDirection(localvelocity);
            return(true);
        }
コード例 #12
0
 public cForceDrag(float friction, cVector3 windvector)
 {
     _windvector = new cVector3();
     _windvector.copy(windvector);
     _intensity = friction;
 }
コード例 #13
0
 public cForceGravity(float gravity, cVector3 pulldirection)
 {
     _pulldirection = new cVector3();
     _pulldirection.copy(pulldirection);
     _intensity = gravity;
 }
コード例 #14
0
ファイル: metric.cs プロジェクト: aaronrcooper/ACFramework
 public void copy(cDistanceAndDirection dd)
 {
     _distance = dd._distance;
     _direction.copy(dd._direction);
 }
コード例 #15
0
ファイル: metric.cs プロジェクト: aaronrcooper/ACFramework
 public cDistanceAndDirection(float dist, cVector3 dir)
 {
     _distance  = dist;
     _direction = new cVector3();
     _direction.copy(dir);
 }
コード例 #16
0
        public void setRoom2()
        {
            Biota.purgeCritters("cCritterWall");
            Biota.purgeCritters("cCritter3Dcharacter");
            Biota.purgeCritters("cCritterBoss");
            setBorder(50.0f, 40.0f, 50.0f);
            cRealBox3 skeleton = new cRealBox3();

            skeleton.copy(_border);
            setSkyBox(skeleton);
            SkyBox.setAllSidesTexture(BitmapRes.Graphics1, 2);
            SkyBox.setSideTexture(cRealBox3.LOY, BitmapRes.Concrete);
            SkyBox.setSideSolidColor(cRealBox3.HIY, Color.Blue);
            _seedcount = 0;
            Player.setMoveBox(new cRealBox3(50.0f, 40.0f, 50.0f));
            wentThrough  = true;
            startNewRoom = Age;

            //add door
            cCritterDoor      pdwall      = new cCritterDoor(new cVector3(_border.Midx, _border.Loy + 4, _border.Loz), new cVector3(_border.Midx, _border.Loy + 10, _border.Loz), 2.0f, 3.0f, this);
            cSpriteTextureBox pspritedoor = new cSpriteTextureBox(pdwall.Skeleton, BitmapRes.Door);

            pdwall.Sprite = pspritedoor;

            float wallThickness = 5.0f, wallHeight = 10.0f;
            //starting block
            cVector3          enda          = new cVector3(Border.Midx, Border.Loy + 1, Border.Hiz);
            cVector3          endb          = new cVector3(Border.Midx, Border.Loy + 1, Border.Hiz - 5);
            cCritterWall      startingBlock = new cCritterWall(enda, endb, wallThickness, wallHeight, this);
            cSpriteTextureBox pspritebox    =
                new cSpriteTextureBox(startingBlock.Skeleton, BitmapRes.Wood2, 16); //Sets all sides

            startingBlock.Sprite = pspritebox;
            //ending block
            cVector3          enda2       = new cVector3(Border.Midx, Border.Loy + 1, Border.Loz + 7);
            cVector3          endb2       = new cVector3(Border.Midx, Border.Loy + 1, Border.Loz);
            cCritterWall      endBlock    = new cCritterWall(enda2, endb2, wallThickness, 8.0f, this);
            cSpriteTextureBox pspritebox2 =
                new cSpriteTextureBox(endBlock.Skeleton, BitmapRes.Wood2, 16); //Sets all sides

            endBlock.Sprite = pspritebox2;
            //floor
            cVector3     enda3 = new cVector3(Border.Midx, Border.Loy, Border.Loz);
            cVector3     endb3 = new cVector3(Border.Midx, Border.Loy, Border.Hiz);
            DamagingWall floor = new DamagingWall(enda3, endb3, 0.5f, 0.5f, this);

            //med pack
            _ptreasure = new cCritterMedpack(this, new cVector3(Border.Midx, Border.Loy + 7, Border.Hiz - 4));

            //sliding walls (spawned based on pos of starting block)
            cVector3 leftEnd = new cVector3();

            leftEnd.addassign(startingBlock.Position.add(new cVector3(0, 4.0f, -0.5f)));
            cVector3 rightEnd = new cVector3();

            rightEnd.copy(leftEnd);
            rightEnd.addassign(new cVector3(0, 0, -5.0f));
            float    thickness = 0.1f, height = 0.3f;
            cVector3 moveAxisandDirection = new cVector3(0, 0, -0.005f);
            cVector3 startPos             = new cVector3();

            startPos.copy(rightEnd);
            cVector3 endPos = new cVector3();

            endPos.copy(startPos);
            endPos.Z = Border.Loz + 9.5f;

            //spawn sliding walls in a separate thread
            new Thread(() =>
                       spawnWall(leftEnd, rightEnd, thickness, height, this, cCritterSlideWall.TYPE.PLATFORM, moveAxisandDirection, false, startPos, endPos)).Start();

            seedCritters();
            Player.moveTo(startingBlock.Position.add(new cVector3(0, 10.0f, 0)));
            new cCritterBossDrFreak(this, endBlock.Position.add(new cVector3(0, 10.0f, 0)), new KnockbackBullet(), 5);
        }