Как использовать 16-битные карты высот с Ogre3d и PhysX - PullRequest
2 голосов
/ 26 июня 2009

Я использую Ogre3D и PhysX.

Когда я загружаю ландшафт из 8-битной карты высот, она выглядит нормально в Visual Debugger.

Посмотрите на первое изображение: http://img44.imageshack.us/gal.php?g=44927650.jpg

Но когда я сохраняю карту высот как 16-битное изображение, я получаю то, что вы видите на втором изображении.

Вот код, который работает нормально с 8-битным PNG:

    mSceneMgr->setWorldGeometry("terrain.cfg" );
    mTSM=static_cast<TerrainSceneManager*>(sceneMgr);

    TerrainOptions mTerrainOptions = mTSM->getOptions();

    //load heihgtmap
    Image mImage;
    mImage.load("isl_h_ph.png", ResourceGroupManager::getSingleton().getWorldResourceGroupName()); //load image

    //write image buffer to pOrigSrc 
    const uchar* pOrigSrc = mImage.getData();
    const uchar* pSrc;
    // image size to mPageSize
    size_t   mPageSize  = mTerrainOptions.pageSize;

    NxActorDesc ActorDesc;

    //set number of segments
    heightFieldDesc = new NxHeightFieldDesc;
    heightFieldDesc->nbColumns      = mPageSize;
    heightFieldDesc->nbRows         = mPageSize;
    heightFieldDesc->verticalExtent   = -1000; 
    heightFieldDesc->convexEdgeThreshold    = 0;

    heightFieldDesc->samples      = new NxU32[mPageSize*mPageSize];   //constructor for every sample?
    heightFieldDesc->sampleStride   = sizeof(NxU32);                    //some sample step = number of samples

    pSrc = pOrigSrc;
    char* currentByte = (char*)heightFieldDesc->samples;     //current sample mb?
    LogManager::getSingletonPtr()->logMessage("+++Heightmap---");
    for (NxU32 row = 0; row < mPageSize; row++)
    {
        for (NxU32 column = 0; column < mPageSize; column++)   //cycle around samples
        {
            pSrc = pOrigSrc + column*mPageSize +row;

            //NxReal s = NxReal(row) / NxReal(mPageSize);
            //NxReal t = NxReal(column) / NxReal(mPageSize);

            NxI16 height = (NxI32)(*pSrc++);
        NxU32 matrixOffset = (row % gMatrixSize) * gMatrixSize + (column % gMatrixSize);

            //LogManager::getSingletonPtr()->logMessage(Ogre::StringConverter::toString(height));
            NxHeightFieldSample* currentSample = (NxHeightFieldSample*)currentByte;
            currentSample->height = height;
        currentSample->materialIndex0 = gMatrix[matrixOffset][1];
        currentSample->materialIndex1 = gMatrix[matrixOffset][2];
        currentSample->tessFlag = gMatrix[matrixOffset][0];
            currentByte += heightFieldDesc->sampleStride;
        }
    }

    heightField = mScene->getPhysicsSDK().createHeightField(*heightFieldDesc);

    NxHeightFieldShapeDesc heightFieldShapeDesc;
    heightFieldShapeDesc.heightField   = heightField;
    heightFieldShapeDesc.shapeFlags      = NX_SF_FEATURE_INDICES | NX_SF_VISUALIZATION;
    heightFieldShapeDesc.group   = 1;
    heightFieldShapeDesc.heightScale   = 18.8f;//1 в Physx = 255 в огре
    heightFieldShapeDesc.rowScale      = mTerrainOptions.scale.x;
    heightFieldShapeDesc.columnScale   = mTerrainOptions.scale.z;
    heightFieldShapeDesc.meshFlags   = NX_MESH_SMOOTH_SPHERE_COLLISIONS;
    heightFieldShapeDesc.materialIndexHighBits = 0;
    heightFieldShapeDesc.holeMaterial = 2;
    ActorDesc.shapes.pushBack(&heightFieldShapeDesc);

Что я должен изменить, чтобы получить загруженное изображение размером 16 бит или выше?

P.S .: Извините за плохой английский

Ответы [ 2 ]

1 голос
/ 26 июня 2009

Ваш pOrigSrc - это uchar, который составляет 8 бит, поэтому вы не получите правильное смещение при этом:

pSrc = pOrigSrc + column*mPageSize +row;

Вы можете исправить это, сначала захватывая шаг вашего изображения перед петлями, что-то вроде этого:

int imageStride = mImage.getBPP() / 8;

, а затем умножьте рассчитанное смещение на шаг, примерно так:

pSrc = pOrigSrc + (column*mPageSize +row)*imageStride;

Это должно позволить вам использовать как 8-битные, так и 16-битные карты высот. PhysX поддерживает только 16-битные карты высот, поэтому вы не можете пойти выше этого уровня.

0 голосов
/ 27 июня 2009

Все символы в вашем коде теперь должны быть короткими, и вам нужно обходить файл 2 байта за раз, а не 1. Потому что 8 бит - это один байт (размер символа или uchar), а 16 биты - два байта, размер короткого или короткого знака без знака.

...