Example #1
0
void __stdcall RVExtension(char *output, int outputSize, const char *function) {
    ZERO_OUTPUT();
    if (!strcmp(function, "version")) {
        strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE);
    } else {
        strncpy_s(output, outputSize, getImagePathFromStructuredText(function).c_str(), _TRUNCATE);
    }
    EXTENSION_RETURN();
}
Example #2
0
void __stdcall RVExtension(char *output, int outputSize, const char *function) {
    ZERO_OUTPUT();

    if (!strcmp(function, "version")) {
        strncpy(output, ACE_FULL_VERSION_STR, outputSize);
    } else {
        std::vector<std::string> argStrings = splitString(function);
        double initSpeed = std::stod(argStrings[0]);
        double airFriction = std::stod(argStrings[1]);
        double angleTarget = std::stod(argStrings[2]);
        double distance = std::stod(argStrings[3]);

        double result = getSolution(initSpeed, airFriction, angleTarget, distance);

        std::stringstream sstream;
        sstream << result;

        strcpy(output, sstream.str().c_str());
        output[outputSize - 1] = '\0';
    }
    EXTENSION_RETURN();
}
Example #3
0
void __stdcall RVExtension(char *output, int outputSize, const char *function)
{
    ZERO_OUTPUT();
    std::stringstream outputStr;
    if (!strcmp(function, "version")) {
        strncpy_s(output, outputSize, ACE_FULL_VERSION_STR, _TRUNCATE);
        EXTENSION_RETURN();
    }

    char* input = _strdup(function);
    char* token = NULL;
    char* next_token = NULL;
    char* mode = strtok_s(input, ":", &next_token);

    if (!strcmp(mode, "retard")) {
        double ballisticCoefficient = 1.0;
        int dragModel = 1;
        double velocity = 0.0;
        double retard = 0.0;

        dragModel = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        ballisticCoefficient = strtod(strtok_s(NULL, ":", &next_token), NULL);
        velocity = strtod(strtok_s(NULL, ":", &next_token), NULL);

        retard = calculateRetard(dragModel, ballisticCoefficient, velocity);
        // int n = sprintf(output,  "%f", retard);

        outputStr << retard;
        strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);

        EXTENSION_RETURN();
    } else if (!strcmp(mode, "atmosphericCorrection")) {
        double ballisticCoefficient = 1.0;
        double temperature = 15.0;
        double pressure = 1013.25;
        double humidity = 0.0;
        char* atmosphereModel;

        ballisticCoefficient = strtod(strtok_s(NULL, ":", &next_token), NULL);
        temperature = strtod(strtok_s(NULL, ":", &next_token), NULL);
        pressure = strtod(strtok_s(NULL, ":", &next_token), NULL);
        humidity = strtod(strtok_s(NULL, ":", &next_token), NULL);
        atmosphereModel = strtok_s(NULL, ":", &next_token);

        ballisticCoefficient = calculateAtmosphericCorrection(ballisticCoefficient, temperature, pressure, humidity, atmosphereModel);
        //int n = sprintf(output,  "%f", ballisticCoefficient);
        outputStr << ballisticCoefficient;
        strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
        EXTENSION_RETURN();
    } else if (!strcmp(mode, "new")) {
        unsigned int index = 0;
        double airFriction = 0.0;
        char* ballisticCoefficientArray;
        char* ballisticCoefficient;
        std::vector<double> ballisticCoefficients;
        char* velocityBoundaryArray;
        char* velocityBoundary;
        std::vector<double> velocityBoundaries;
        char* atmosphereModel;
        int dragModel = 1;
        double stabilityFactor = 1.5;
        int twistDirection = 1;
        double transonicStabilityCoef = 1;
        double muzzleVelocity = 850;
        char* originArray;
        char* originEntry;
        std::vector<double> origin;
        double latitude = 0.0;
        double temperature = 0.0;
        double altitude = 0.0;
        double humidity = 0.0;
        double overcast = 0.0;
        double tickTime = 0.0;

        index = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        airFriction = strtod(strtok_s(NULL, ":", &next_token), NULL);
        ballisticCoefficientArray = strtok_s(NULL, ":", &next_token);
        ballisticCoefficientArray++;
        ballisticCoefficientArray[strlen(ballisticCoefficientArray) - 1] = 0;
        ballisticCoefficient = strtok_s(ballisticCoefficientArray, ",", &token);
        while (ballisticCoefficient != NULL) {
            ballisticCoefficients.push_back(strtod(ballisticCoefficient, NULL));
            ballisticCoefficient = strtok_s(NULL, ",", &token);
        }
        velocityBoundaryArray = strtok_s(NULL, ":", &next_token);
        velocityBoundaryArray++;
        velocityBoundaryArray[strlen(velocityBoundaryArray) - 1] = 0;
        velocityBoundary = strtok_s(velocityBoundaryArray, ",", &token);
        while (velocityBoundary != NULL) {
            velocityBoundaries.push_back(strtod(velocityBoundary, NULL));
            velocityBoundary = strtok_s(NULL, ",", &token);
        }
        atmosphereModel = strtok_s(NULL, ":", &next_token);
        dragModel = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        stabilityFactor = strtod(strtok_s(NULL, ":", &next_token), NULL);
        twistDirection = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        muzzleVelocity = strtod(strtok_s(NULL, ":", &next_token), NULL);
        transonicStabilityCoef = strtod(strtok_s(NULL, ":", &next_token), NULL);
        originArray = strtok_s(NULL, ":", &next_token);
        originArray++;
        originArray[strlen(originArray) - 1] = 0;
        originEntry = strtok_s(originArray, ",", &token);
        while (originEntry != NULL) {
            origin.push_back(strtod(originEntry, NULL));
            originEntry = strtok_s(NULL, ",", &token);
        }
        latitude = strtod(strtok_s(NULL, ":", &next_token), NULL);
        temperature = strtod(strtok_s(NULL, ":", &next_token), NULL);
        altitude = strtod(strtok_s(NULL, ":", &next_token), NULL);
        humidity = strtod(strtok_s(NULL, ":", &next_token), NULL);
        overcast = strtod(strtok_s(NULL, ":", &next_token), NULL);
        tickTime = strtod(strtok_s(NULL, ":", &next_token), NULL);
        tickTime += strtod(strtok_s(NULL, ":", &next_token), NULL);

        while (index >= bulletDatabase.size()) {
            Bullet bullet;
            bulletDatabase.push_back(bullet);
        }

        bulletDatabase[index].airFriction = airFriction;
        bulletDatabase[index].ballisticCoefficients = ballisticCoefficients;
        bulletDatabase[index].velocityBoundaries = velocityBoundaries;
        bulletDatabase[index].atmosphereModel = atmosphereModel;
        bulletDatabase[index].dragModel = dragModel;
        bulletDatabase[index].stabilityFactor = stabilityFactor;
        bulletDatabase[index].twistDirection = twistDirection;
        bulletDatabase[index].transonicStabilityCoef = transonicStabilityCoef;
        bulletDatabase[index].muzzleVelocity = muzzleVelocity;
        bulletDatabase[index].origin = origin;
        bulletDatabase[index].latitude = latitude / 180 * M_PI;
        bulletDatabase[index].temperature = temperature;
        bulletDatabase[index].altitude = altitude;
        bulletDatabase[index].humidity = humidity;
        bulletDatabase[index].overcast = overcast;
        bulletDatabase[index].startTime = tickTime;
        bulletDatabase[index].lastFrame = tickTime;
        bulletDatabase[index].bcDegradation = 1.0;
        bulletDatabase[index].randSeed = 0;

        strncpy_s(output, outputSize, "", _TRUNCATE);
        EXTENSION_RETURN();
    } else if (!strcmp(mode, "simulate")) {
        // simulate:0:[-0.109985,542.529,-3.98301]:[3751.57,5332.23,214.252]:[0.598153,2.38829,0]:28.6:0:0.481542:0:215.16
        unsigned int index = 0;
        char* velocityArray;
        double velocity[3] = { 0.0, 0.0, 0.0 };
        char* positionArray;
        double position[3] = { 0.0, 0.0, 0.0 };
        char* windArray;
        double wind[3];
        double heightAGL = 0.0;
        double tickTime = 0.0;

        index = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        velocityArray = strtok_s(NULL, ":", &next_token);
        velocityArray++;
        velocityArray[strlen(velocityArray) - 1] = 0;
        velocity[0] = strtod(strtok_s(velocityArray, ",", &token), NULL);
        velocity[1] = strtod(strtok_s(NULL, ",", &token), NULL);
        velocity[2] = strtod(strtok_s(NULL, ",", &token), NULL);
        positionArray = strtok_s(NULL, ":", &next_token);
        positionArray++;
        positionArray[strlen(positionArray) - 1] = 0;
        position[0] = strtod(strtok_s(positionArray, ",", &token), NULL);
        position[1] = strtod(strtok_s(NULL, ",", &token), NULL);
        position[2] = strtod(strtok_s(NULL, ",", &token), NULL);
        windArray = strtok_s(NULL, ":", &next_token);
        windArray++;
        windArray[strlen(windArray) - 1] = 0;
        wind[0] = strtod(strtok_s(windArray, ",", &token), NULL);
        wind[1] = strtod(strtok_s(NULL, ",", &token), NULL);
        wind[2] = strtod(strtok_s(NULL, ",", &token), NULL);
        heightAGL = strtod(strtok_s(NULL, ":", &next_token), NULL);
        tickTime = strtod(strtok_s(NULL, ":", &next_token), NULL);
        tickTime += strtod(strtok_s(NULL, ":", &next_token), NULL);

        if (bulletDatabase[index].randSeed == 0) {
            int angle = (int)round(atan2(velocity[0], velocity[1]) * 360 / M_PI);
            bulletDatabase[index].randSeed = (unsigned)(720 + angle) % 720;
            bulletDatabase[index].randSeed *= 3;
            bulletDatabase[index].randSeed += (unsigned)round(abs(velocity[2]) / 2);
            bulletDatabase[index].randSeed *= 3;
            bulletDatabase[index].randSeed += (unsigned)round(abs(bulletDatabase[index].origin[0] / 2));
            bulletDatabase[index].randSeed *= 3;
            bulletDatabase[index].randSeed += (unsigned)round(abs(bulletDatabase[index].origin[1] / 2));
            bulletDatabase[index].randSeed *= 3;
            bulletDatabase[index].randSeed += (unsigned)abs(bulletDatabase[index].temperature) * 10;
            bulletDatabase[index].randSeed *= 3;
            bulletDatabase[index].randSeed += (unsigned)abs(bulletDatabase[index].humidity) * 10;
            bulletDatabase[index].randGenerator.seed(bulletDatabase[index].randSeed);
        }

        double ballisticCoefficient = 1.0;
        double dragRef = 0.0;
        double drag = 0.0;
        double accelRef[3] = { 0.0, 0.0, 0.0 };
        double accel[3] = { 0.0, 0.0, 0.0 };
        double TOF = 0.0;
        double deltaT = 0.0;
        double bulletSpeed;
        double trueVelocity[3] = { 0.0, 0.0, 0.0 };
        double trueSpeed = 0.0;
        double temperature = 0.0;
        double pressure = 1013.25;
        double windSpeed = 0.0;
        double windAttenuation = 1.0;
        double velocityOffset[3] = { 0.0, 0.0, 0.0 };

        TOF = tickTime - bulletDatabase[index].startTime;

        deltaT = tickTime - bulletDatabase[index].lastFrame;
        bulletDatabase[index].lastFrame = tickTime;

        bulletSpeed = sqrt(pow(velocity[0], 2) + pow(velocity[1], 2) + pow(velocity[2], 2));

        windSpeed = sqrt(pow(wind[0], 2) + pow(wind[1], 2) + pow(wind[2], 2));
        if (windSpeed > 0.1) {
            double windSourceTerrain[3];

            windSourceTerrain[0] = position[0] - wind[0] / windSpeed * 100;
            windSourceTerrain[1] = position[1] - wind[1] / windSpeed * 100;
            windSourceTerrain[2] = position[2] - wind[2] / windSpeed * 100;

            int gridX = (int)floor(windSourceTerrain[0] / 50);
            int gridY = (int)floor(windSourceTerrain[1] / 50);
            int gridCell = gridX * map->mapGrids + gridY;

            if (gridCell >= 0 && (std::size_t)gridCell < map->gridHeights.size() && (std::size_t)gridCell < map->gridBuildingNums.size()) {
                double gridHeight = map->gridHeights[gridCell];

                if (gridHeight > position[2]) {
                    double angle = atan((gridHeight - position[2]) / 100);
                    windAttenuation *= pow(abs(cos(angle)), 2);
                }
            }
        }

        if (windSpeed > 0.1) {
            double windSourceObstacles[3];

            windSourceObstacles[0] = position[0] - wind[0] / windSpeed * 25;
            windSourceObstacles[1] = position[1] - wind[1] / windSpeed * 25;
            windSourceObstacles[2] = position[2] - wind[2] / windSpeed * 25;

            if (heightAGL > 0 && heightAGL < 20) {
                double roughnessLength = calculateRoughnessLength(windSourceObstacles[0], windSourceObstacles[1]);
                windAttenuation *= abs(log(heightAGL / roughnessLength) / log(20 / roughnessLength));
            }
        }

        if (windAttenuation < 1) {
            wind[0] *= windAttenuation;
            wind[1] *= windAttenuation;
            wind[2] *= windAttenuation;
            windSpeed = sqrt(pow(wind[0], 2) + pow(wind[1], 2) + pow(wind[2], 2));
        }

        trueVelocity[0] = velocity[0] - wind[0];
        trueVelocity[1] = velocity[1] - wind[1];
        trueVelocity[2] = velocity[2] - wind[2];
        trueSpeed = sqrt(pow(trueVelocity[0], 2) + pow(trueVelocity[1], 2) + pow(trueVelocity[2], 2));

        double speedOfSound = 331.3 + (0.6 * temperature);
        double transonicSpeed = 394 + (0.6 * temperature);
        if (bulletDatabase[index].transonicStabilityCoef < 1.0f && bulletSpeed < transonicSpeed && bulletSpeed > speedOfSound) {
            std::uniform_real_distribution<double> distribution(-10.0, 10.0);
            double coef = 1.0f - bulletDatabase[index].transonicStabilityCoef;

            trueVelocity[0] += distribution(bulletDatabase[index].randGenerator) * coef;
            trueVelocity[1] += distribution(bulletDatabase[index].randGenerator) * coef;
            trueVelocity[2] += distribution(bulletDatabase[index].randGenerator) * coef;
            double speed = sqrt(pow(trueVelocity[0], 2) + pow(trueVelocity[1], 2) + pow(trueVelocity[2], 2));

            trueVelocity[0] *= trueSpeed / speed;
            trueVelocity[1] *= trueSpeed / speed;
            trueVelocity[2] *= trueSpeed / speed;

            bulletDatabase[index].bcDegradation *= pow(0.993, coef);
        };

        temperature = bulletDatabase[index].temperature - 0.0065 * position[2];
        pressure = (1013.25 - 10 * bulletDatabase[index].overcast) * pow(1 - (0.0065 * (bulletDatabase[index].altitude + position[2])) / (273.15 + temperature + 0.0065 * bulletDatabase[index].altitude), 5.255754495);

        if (bulletDatabase[index].ballisticCoefficients.size() == bulletDatabase[index].velocityBoundaries.size() + 1) {
            dragRef = deltaT * bulletDatabase[index].airFriction * bulletSpeed * bulletSpeed;

            accelRef[0] = (velocity[0] / bulletSpeed) * dragRef;
            accelRef[1] = (velocity[1] / bulletSpeed) * dragRef;
            accelRef[2] = (velocity[2] / bulletSpeed) * dragRef;

            velocityOffset[0] -= accelRef[0];
            velocityOffset[1] -= accelRef[1];
            velocityOffset[2] -= accelRef[2];

            ballisticCoefficient = bulletDatabase[index].ballisticCoefficients[0];
            for (int i = (int)bulletDatabase[index].velocityBoundaries.size() - 1; i >= 0; i = i - 1) {
                if (bulletSpeed < bulletDatabase[index].velocityBoundaries[i]) {
                    ballisticCoefficient = bulletDatabase[index].ballisticCoefficients[i + 1];
                    break;
                }
            }

            ballisticCoefficient = calculateAtmosphericCorrection(ballisticCoefficient, temperature, pressure, bulletDatabase[index].humidity, bulletDatabase[index].atmosphereModel);
            ballisticCoefficient *= bulletDatabase[index].bcDegradation;
            drag = deltaT * calculateRetard(bulletDatabase[index].dragModel, ballisticCoefficient, trueSpeed);
            accel[0] = (trueVelocity[0] / trueSpeed) * drag;
            accel[1] = (trueVelocity[1] / trueSpeed) * drag;
            accel[2] = (trueVelocity[2] / trueSpeed) * drag;

            velocityOffset[0] -= accel[0];
            velocityOffset[1] -= accel[1];
            velocityOffset[2] -= accel[2];
        } else {
            double airDensity = calculateAirDensity(temperature, pressure, bulletDatabase[index].humidity);
            double airFriction = bulletDatabase[index].airFriction * airDensity / STD_AIR_DENSITY_ICAO;

            if (airFriction != bulletDatabase[index].airFriction || windSpeed > 0) {
                dragRef = deltaT * bulletDatabase[index].airFriction * bulletSpeed * bulletSpeed;

                accelRef[0] = (velocity[0] / bulletSpeed) * dragRef;
                accelRef[1] = (velocity[1] / bulletSpeed) * dragRef;
                accelRef[2] = (velocity[2] / bulletSpeed) * dragRef;

                velocityOffset[0] -= accelRef[0];
                velocityOffset[1] -= accelRef[1];
                velocityOffset[2] -= accelRef[2];

                drag = deltaT * airFriction * trueSpeed * trueSpeed;
                accel[0] = (trueVelocity[0] / trueSpeed) * drag;
                accel[1] = (trueVelocity[1] / trueSpeed) * drag;
                accel[2] = (trueVelocity[2] / trueSpeed) * drag;

                velocityOffset[0] += accel[0];
                velocityOffset[1] += accel[1];
                velocityOffset[2] += accel[2];
            }
        }

        if (TOF > 0) {
            double bulletDir = atan2(velocity[0], velocity[1]);
            double spinAccel = bulletDatabase[index].twistDirection * (0.0482251 * (bulletDatabase[index].stabilityFactor + 1.2)) / pow(TOF, 0.17);
            velocityOffset[0] += sin(bulletDir + M_PI / 2) * spinAccel * deltaT;
            velocityOffset[1] += cos(bulletDir + M_PI / 2) * spinAccel * deltaT;
        }

        double lat = bulletDatabase[index].latitude;
        accel[0] = 2 * EARTH_ANGULAR_SPEED * +(velocity[1] * sin(lat) - velocity[2] * cos(lat));
        accel[1] = 2 * EARTH_ANGULAR_SPEED * -(velocity[0] * sin(lat));
        accel[2] = 2 * EARTH_ANGULAR_SPEED * +(velocity[0] * cos(lat));

        velocityOffset[0] += accel[0] * deltaT;
        velocityOffset[1] += accel[1] * deltaT;
        velocityOffset[2] += accel[2] * deltaT;

        outputStr << "_bullet setVelocity (_bulletVelocity vectorAdd [" << velocityOffset[0] << "," << velocityOffset[1] << "," << velocityOffset[2] << "]);";
        strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
        EXTENSION_RETURN();
    } else if (!strcmp(mode, "set")) {
        int height = 0;
        int numObjects = 0;
        int surfaceIsWater = 0;

        height = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        numObjects = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        surfaceIsWater = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);

        map->gridHeights.push_back(height);
        map->gridBuildingNums.push_back(numObjects);
        map->gridSurfaceIsWater.push_back(surfaceIsWater);

        strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
        EXTENSION_RETURN();
    } else if (!strcmp(mode, "init")) {
        int mapSize = 0;
        int mapGrids = 0;
        unsigned int gridCells = 0;

        worldName = strtok_s(NULL, ":", &next_token);
        mapSize = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);

        mapGrids = (int)ceil((double)mapSize / 50.0) + 1;
        gridCells = mapGrids * mapGrids;

        map = &mapDatabase[worldName];
        if (map->gridHeights.size() == gridCells) {
            outputStr << "Terrain already initialized";
            strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
            EXTENSION_RETURN();
        }

        map->mapSize = mapSize;
        map->mapGrids = mapGrids;
        map->gridHeights.clear();
        map->gridBuildingNums.clear();
        map->gridSurfaceIsWater.clear();
        map->gridHeights.reserve(gridCells);
        map->gridBuildingNums.reserve(gridCells);
        map->gridSurfaceIsWater.reserve(gridCells);

        strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
        EXTENSION_RETURN();
    } else if (!strcmp(mode, "zeroAngleVanilla")) {
        double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double initSpeed = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double airFriction = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL);

        double zeroAngle = calculateVanillaZeroAngle(zeroRange, initSpeed, airFriction, boreHeight);

        outputStr << DEGREES(zeroAngle);
        strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
        EXTENSION_RETURN();
    } else if (!strcmp(mode, "zeroAngle")) {
        double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double muzzleVelocity = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double temperature = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double pressure = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double humidity = strtod(strtok_s(NULL, ":", &next_token), NULL);
        double ballisticCoefficient = strtod(strtok_s(NULL, ":", &next_token), NULL);
        int dragModel = strtol(strtok_s(NULL, ":", &next_token), NULL, 10);
        char* atmosphereModel = strtok_s(NULL, ":", &next_token);

        double zeroAngle = calculateZeroAngle(zeroRange, muzzleVelocity, boreHeight, temperature, pressure, humidity, ballisticCoefficient, dragModel, atmosphereModel);

        outputStr << DEGREES(zeroAngle);
        strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
        EXTENSION_RETURN();
    }
    strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);
    EXTENSION_RETURN();
}