2009-06-26 14 views
2

Ich benutze Ogre3D und PhysX.Wie verwende ich 16bit heightmaps mit Ogre3d und PhysX

Wenn ich ein Terrain aus einer 8-Bit-Höhenkarte lade, sieht es auf Visual Debugger normal aus.

Blick auf den ersten Bild: http://img44.imageshack.us/gal.php?g=44927650.jpg

Aber wenn ich die Höhenkarte als 16bit Bild speichern, bekomme ich, was Sie auf dem zweiten Bild zu sehen.

Hier ist der Code, funktioniert das ist mit 8bit PNG normal:

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); 

Was soll ich ändern 16bit oder höher Bild geladen zum Laufen zu bringen?

PS: Sorry für schlechtes Englisch

Antwort

1

Ihre pOrigSrc ist ein uchar, die 8 Bit ist, so dass Sie nicht immer den richtigen Offset, wenn Sie dies tun:

pSrc = pOrigSrc + column*mPageSize +row; 

Sie können dieses Problem beheben indem man zuerst vor Ihrer Schleifen den Schritt des Bildes greifen, so etwas wie dieses:

int imageStride = mImage.getBPP()/8; 

und dann multiplizieren Sie Ihre durch den Schritt Offset berechnet, so etwas wie folgt aus:

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

Das sollte Ihnen ermöglichen, 8-Bit- und 16-Bit-Höhenkarten zu verwenden. PhysX unterstützt nur 16-Bit-Höhenkarten. Sie können also nicht höher gehen.

+0

Dank jetzt sein Blick ein wenig schön =) aber immer noch nicht gut http://img34.imageshack.us/i/new161.jpg/ –

0

Alle Zeichen in Ihrem Code müssen jetzt kurz sein, und Sie müssen die Datei 2 Byte auf einmal durchlaufen, nicht 1. Weil 8 Bits ein Byte (die Größe eines Char oder Uchar) und 16 Bits sind zwei Bytes, die Größe eines kurzen oder vorzeichenlosen Kurzschlusses.

+0

wie nur kurz, wenn getData Rückkehr zu bekommen uchar –

Verwandte Themen