Пример #1
0
    // ****************************************************************************************************
    // ****************************************************************************************************
    //			BACKGROUND FUNCTIONS
    // ****************************************************************************************************
    CC_Unit convertUnit_CCUnit(Unit u)
    {
        CC_Unit ccu = new CC_Unit(u);

        u.setMyCC_Unit(ccu);
        return(ccu);
    }
Пример #2
0
 public void RemoveCCUnit(CC_Unit ccu)
 {
     if (_units.Contains(ccu))
     {
         _units.Remove(ccu);
     }
 }
Пример #3
0
    private void applyPredictiveDiscomfort(float numSec, CC_Unit cc_u)
    {
        Vector2 newLoc;
        float   sc;

        Vector2[] cc_u_pos = cc_u.getPositions();

        for (int k = 0; k < cc_u_pos.Length; k++)
        {
            Vector2 xprime = cc_u_pos[k] + cc_u.getVelocity() * numSec;

            float vfMag = Vector2.Distance(cc_u_pos[k], xprime);

            for (int i = 5; i < vfMag; i++)
            {
                newLoc = Vector2.MoveTowards(cc_u_pos[k], xprime, i);

                sc          = (vfMag - i) / vfMag;                                      // inverse scale
                float[,] gP = linear1stOrderSplat(newLoc, sc * CCvals.gP_weight);

                int xInd = (int)Math.Floor((double)newLoc.x);
                int yInd = (int)Math.Floor((double)newLoc.y);

                if (isPointValid(xInd, yInd))
                {
                    float gPt = readDataFromPoint_gP(xInd, yInd);
                    writeDataToPoint_gP(xInd, yInd, gPt + gP [0, 0]);
                }
                if (isPointValid(xInd + 1, yInd))
                {
                    float gPt = readDataFromPoint_gP(xInd + 1, yInd);
                    writeDataToPoint_gP(xInd + 1, yInd, gPt + gP [1, 0]);
                }
                if (isPointValid(xInd, yInd + 1))
                {
                    float gPt = readDataFromPoint_gP(xInd, yInd + 1);
                    writeDataToPoint_gP(xInd, yInd + 1, gPt + gP [0, 1]);
                }
                if (isPointValid(xInd + 1, yInd + 1))
                {
                    float gPt = readDataFromPoint_gP(xInd + 1, yInd + 1);
                    writeDataToPoint_gP(xInd + 1, yInd + 1, gPt + gP [1, 1]);
                }
            }
        }
    }
Пример #4
0
    // ******************************************************************************************
    // ******************************************************************************************
    // ******************************************************************************************
    //                          FIELD SOLVING FUNCTIONS
    // ******************************************************************************************
    private void computeDensityField(CC_Unit cc_u)
    {
        Vector2[] cc_u_pos = cc_u.getPositions();

        for (int i = 0; i < cc_u_pos.Length; i++)
        {
            int xInd = (int)Math.Floor((double)cc_u_pos[i].x);
            int yInd = (int)Math.Floor((double)cc_u_pos[i].y);

            float[,] rho = linear1stOrderSplat(cc_u_pos[i].x, cc_u_pos[i].y, CCvals.rho_sc);

            if (isPointValid(xInd, yInd))
            {
                float rt = readDataFromPoint_rho(xInd, yInd);
                writeDataToPoint_rho(xInd, yInd, rt + rho [0, 0]);
            }
            if (isPointValid(xInd + 1, yInd))
            {
                float rt = readDataFromPoint_rho(xInd + 1, yInd);
                writeDataToPoint_rho(xInd + 1, yInd, rt + rho [1, 0]);
            }
            if (isPointValid(xInd, yInd + 1))
            {
                float rt = readDataFromPoint_rho(xInd, yInd + 1);
                writeDataToPoint_rho(xInd, yInd + 1, rt + rho [0, 1]);
            }
            if (isPointValid(xInd + 1, yInd + 1))
            {
                float rt = readDataFromPoint_rho(xInd + 1, yInd + 1);
                writeDataToPoint_rho(xInd + 1, yInd + 1, rt + rho [1, 1]);
            }

            computeVelocityFieldPoint(xInd, yInd, cc_u.getVelocity());
            computeVelocityFieldPoint(xInd + 1, yInd, cc_u.getVelocity());
            computeVelocityFieldPoint(xInd, yInd + 1, cc_u.getVelocity());
            computeVelocityFieldPoint(xInd + 1, yInd + 1, cc_u.getVelocity());
        }
    }
Пример #5
0
    // ******************************************************************************************
    //                          FIELD SOLVING FUNCTIONS
    // ******************************************************************************************
    private void computeDensityField(CC_Unit ccu)
    {
        // grab properties of the CC Unit
        var footprint = ccu.GetFootprint().Rotate(-ccu.Rotation());
        var anchor    = ccu.Position();

        // compute the footprint's half-dimensions
        var xHalf = footprint.GetLength(0) / 2f;
        var yHalf = footprint.GetLength(1) / 2f;

        // translate the anchor so it's centered about our unit
        anchor -= new Vector2(xHalf, yHalf);
        // finally, perform bilinear interpolation of the footprint at our anchor
        var footprintInterp = footprint.BilinearInterpolation(anchor);

        // offsets - floor produces smoothest interpolated position stamps
        var xOffset = Mathf.FloorToInt(anchor.x);
        var yOffset = Mathf.FloorToInt(anchor.y);

        // scan the grid, stamping the footprint onto the tile
        for (int x = 0; x < footprintInterp.GetLength(0); x++)
        {
            for (int y = 0; y < footprintInterp.GetLength(1); y++)
            {
                // get the rho value
                float rho = footprintInterp[x, y];
                // only perform storage functions if there is a density value
                if (rho > 0)
                {
                    var xIndex = x + xOffset;
                    var yIndex = y + yOffset;
                    // add rho to the in-place density
                    addDataToPoint_rho(xIndex, yIndex, rho);
                }
            }
        }
    }
Пример #6
0
 public void removeCCUnit(CC_Unit ccu)
 {
     _units.Remove(ccu);
 }
Пример #7
0
    // 0000000000000000000000000000000000000000000000000000000000
    // 0000000000000000000000000000000000000000000000000000000000

    public void addNewCCUnit(CC_Unit ccu)
    {
        _units.Add(ccu);
    }
Пример #8
0
 public void TrackUnit(CC_Unit ccu)
 {
     ccFields.AddNewCCUnit(ccu);
 }
Пример #9
0
 public void setMyCC_Unit(CC_Unit ccu)
 {
     _myCCU = ccu;
 }
Пример #10
0
    // **********************************************************************
    //      Predictive velocity fields
    // **********************************************************************
    private void applyPredictiveVelocity(CC_Unit ccu)
    {
        // TODO: Only apply predictive velocity to continuous segments, ie.
        //      if a portion of this predictive path is blocked by impassable
        //      terrain, we should not apply predictive velocity beyond that
        //      point

        // fetch unit properties
        var speed = ccu.Speed();

        // compute values
        var distance  = (int)Math.Ceiling(speed * CCValues.S.v_predictiveSeconds);
        var footprint = ccu.GetFootprint();
        var height    = footprint.GetLength(1);

        // (1) create a rect with Length = predictive distance, Height = Unit footprint height
        //var footprintEnd = (int)Math.Floor(footprint.GetLength(0) / 2f);
        var footprintEnd = Mathf.FloorToInt(ccu.Falloff() + ccu.SizeX - 1);
        var predictive   = new float[footprintEnd + distance, height];

        // (2) build half of the footprint into the predictive rect
        for (int i = 0; i < footprintEnd; i++)
        {
            for (int k = 0; k < height; k++)
            {
                predictive[i, k] = footprint[i, k];
            }
        }

        // (3a) record the "vertical slice" of the unit footprint
        var slice = new float[height];

        for (int i = 0; i < slice.Length; i++)
        {
            slice[i] = footprint[footprintEnd, i];
        }

        // (3b) scale the vertical slice along the length of the rect
        // determine falloff rates
        var start = (CCValues.S.f_rhoMax + CCValues.S.f_rhoMin) / 2;
        var end   = 0f; // CCValues.S.f_rhoMin / 4f;
        // track iteration
        int c = 0;

        for (int i = footprintEnd; i < predictive.GetLength(0); i++)
        {
            // taper from <start> down to <end>
            var scalar = (end - start) / distance * c + start;
            c++;
            for (int k = 0; k < height; k++)
            {
                // build the predictive velocity rect in front of the footprint
                predictive[i, k] = slice[k] * scalar;
            }
        }

        // (4) rotate the rect
        var yEuler = ccu.Rotation();
        // Unity y-euler rotations start at +z (+y in 2D) and move CW.
        // Academic rotations are described as CCW from the +x axis, which is what
        // many of our derivations are based, so we convert here.
        var degrees = Mathf.Repeat(90 - yEuler, 360);
        var radians = degrees * Mathf.Deg2Rad;
        var rotated = predictive.Rotate(degrees);

        // (5) determine anchor position - do this by taking the "perfect" center
        //     and applying the same translations/rotations that our rotate process
        //     applies
        //   (i) declare unit location in original footprint center
        var unitOffset = new Vector2(footprint.GetLength(0) / 2f, height / 2f);

        //   (ii) translate by predictive velocity half-shape to center on (0,0)
        unitOffset += new Vector2(-predictive.GetLength(0) / 2f, -height / 2f);
        //   (iii) rotate the point about (0,0) by our unit's rotation
        unitOffset = unitOffset.Rotate(radians);
        //   (iv) translate back by rotated shape half-space
        unitOffset += new Vector2(rotated.GetLength(0) / 2f, rotated.GetLength(1) / 2f);

        // finally, translate the anchor to be positioned on the unit
        var anchor = ccu.Position() - unitOffset;

        // (6) inteprolate the final result
        var final = rotated.BilinearInterpolation(anchor);

        // offsets - floor produces smoothest interpolated position stamps
        var xOffset = Mathf.FloorToInt(anchor.x);
        var yOffset = Mathf.FloorToInt(anchor.y);

        // (7) add the density and velocity along the length of the path,
        // scaling each by the value of the rect
        var direction = new Vector2(1, 0).Rotate(radians);
        var velocity  = direction * speed;

        for (int x = 0; x < final.GetLength(0); x++)
        {
            for (int y = 0; y < final.GetLength(1); y++)
            {
                var xIndex = x + xOffset;
                var yIndex = y + yOffset;
                // add rho and velocity to existing data
                addDataToPoint_rho(xIndex, yIndex, final[x, y]);
                addDataToPoint_vAve(xIndex, yIndex, final[x, y] * velocity);
            }
        }
    }