void ReliefApp::GenerateRelief() { //Get depth data Ogre::TexturePtr depthTex = Ogre::TextureManager::getSingleton().createManual( "DepthTexture", // name Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, // type 512, // width 512, // height 0, // number of mipmaps //Ogre::PF_B8G8R8A8, // pixel format Ogre::PF_FLOAT32_R, Ogre::TU_RENDERTARGET ); Ogre::RenderTarget* pTarget = depthTex->getBuffer()->getRenderTarget(); Ogre::Camera* pOrthCam = MagicCore::RenderSystem::GetSingleton()->GetMainCamera(); pOrthCam->setProjectionType(Ogre::PT_ORTHOGRAPHIC); pOrthCam->setOrthoWindow(3, 3); pOrthCam->setPosition(0, 0, 3); pOrthCam->lookAt(0, 0, 0); pOrthCam->setAspectRatio(1.0); pOrthCam->setNearClipDistance(0.5); pOrthCam->setFarClipDistance(5); Ogre::Viewport* pViewport = pTarget->addViewport(pOrthCam); pViewport->setDimensions(0, 0, 1, 1); MagicCore::RenderSystem::GetSingleton()->RenderLightMesh3D("RenderMesh", "Depth", mpLightMesh); MagicCore::RenderSystem::GetSingleton()->Update(); Ogre::Image img; depthTex->convertToImage(img); std::vector<double> heightField(512 * 512); for(int x = 0; x < 512; x++) { for(int y = 0; y < 512; y++) { heightField.at(x * 512 + y) = (img.getColourAt(x, 511 - y, 0))[1]; } } Ogre::TextureManager::getSingleton().remove("DepthTexture"); // MagicDGP::LightMesh3D* pReliefMesh = MagicDGP::ReliefGeneration::PlaneReliefFromHeightField(heightField, 511, 511); //MagicDGP::LightMesh3D* pReliefMesh = MagicDGP::ReliefGeneration::CylinderReliefFromHeightField(heightField, 511, 511); if (pReliefMesh != NULL) { delete mpLightMesh; mpLightMesh = pReliefMesh; mpLightMesh->UnifyPosition(2); mpLightMesh->UpdateNormal(); } MagicCore::RenderSystem::GetSingleton()->SetupCameraDefaultParameter(); MagicCore::RenderSystem::GetSingleton()->RenderLightMesh3D("RenderMesh", "MyCookTorrance", mpLightMesh); }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::setBrushName(const std::string& brush) { mBrushName = brush; if(!mDecalTexture.isNull()) { Ogre::Image img; img.load(brush,"Brushes"); unsigned char *dataptr = OGRE_ALLOC_T(unsigned char, img.getWidth() * img.getHeight() * 3, Ogre::MEMCATEGORY_GEOMETRY); Ogre::PixelBox resultbox(img.getWidth(),img.getHeight(),1,Ogre::PF_B8G8R8,dataptr); Ogre::PixelUtil::bulkPixelConversion(img.getPixelBox(), resultbox); resultbox.setConsecutive(); int pos = 0; Ogre::ColourValue colval; for(unsigned int x = 0;x < img.getHeight() * img.getWidth();x++) { dataptr[pos] = 0; dataptr[pos + 1] = 0; dataptr[pos + 2] *= 0.8f; pos += 3; } mDecalTexture->setHeight(img.getHeight()); mDecalTexture->setWidth(img.getWidth()); Ogre::HardwarePixelBufferSharedPtr ptr = mDecalTexture->getBuffer(); ptr->blitFromMemory(resultbox); OGRE_FREE(dataptr, Ogre::MEMCATEGORY_GEOMETRY); img.resize(mBrushSize, mBrushSize); img.resize(BRUSH_DATA_SIZE, BRUSH_DATA_SIZE); pos = 0; Ogre::ColourValue cval; for(unsigned int y = 0;y < BRUSH_DATA_SIZE ;y++) { pos = ((BRUSH_DATA_SIZE - 1) - y) * BRUSH_DATA_SIZE; for(unsigned int x = 0;x < BRUSH_DATA_SIZE ;x++) { cval = img.getColourAt(x,y,0); mBrushData[pos] = cval.r; pos++; } } }
void GlobalMap::exploreCell(int cellX, int cellY) { float originX = static_cast<float>((cellX - mMinX) * mCellSize); // NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is float originY = static_cast<float>(mHeight - (cellY + 1 - mMinY) * mCellSize); if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY) return; Ogre::TexturePtr localMapTexture = Ogre::TextureManager::getSingleton().getByName("Cell_" + boost::lexical_cast<std::string>(cellX) + "_" + boost::lexical_cast<std::string>(cellY)); if (!localMapTexture.isNull()) { int mapWidth = localMapTexture->getWidth(); int mapHeight = localMapTexture->getHeight(); mOverlayTexture->load(); mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(), Ogre::Image::Box(0,0,mapWidth,mapHeight), Ogre::Image::Box(static_cast<Ogre::uint32>(originX), static_cast<Ogre::uint32>(originY), static_cast<Ogre::uint32>(originX + mCellSize), static_cast<Ogre::uint32>(originY + mCellSize))); Ogre::Image backup; std::vector<Ogre::uchar> data; data.resize(mCellSize*mCellSize*4, 0); backup.loadDynamicImage(&data[0], mCellSize, mCellSize, Ogre::PF_A8B8G8R8); localMapTexture->getBuffer()->blitToMemory(Ogre::Image::Box(0,0,mapWidth,mapHeight), backup.getPixelBox()); for (int x=0; x<mCellSize; ++x) for (int y=0; y<mCellSize; ++y) { assert (originX+x < mOverlayImage.getWidth()); assert (originY+y < mOverlayImage.getHeight()); assert (x < int(backup.getWidth())); assert (y < int(backup.getHeight())); mOverlayImage.setColourAt(backup.getColourAt(x, y, 0), static_cast<size_t>(originX + x), static_cast<size_t>(originY + y), 0); } } }
void TerrainGeometryManager::initBlendMaps(int x, int z, Ogre::Terrain* terrain ) { bool debugBlendMaps = BOPT("DebugBlendMaps", false); int layerCount = terrain->getLayerCount(); for (int i = 1; i < layerCount; i++) { blendLayerInfo_t &bi = blendInfo[i]; if(bi.blendMapTextureFilename.empty()) continue; Ogre::Image img; //std::pair<uint8,uint8> textureIndex = terrain->getLayerBlendTextureIndex(i); //uint8 bti = terrain->getBlendTextureIndex(i); try { img.load(bi.blendMapTextureFilename, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); } catch(Exception &e) { LOG("Error loading blendmap: " + bi.blendMapTextureFilename + " : " + e.getFullDescription()); continue; } TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(i); // resize that blending map so it will fit Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize(); if (img.getWidth() != blendmapSize) img.resize(blendmapSize, blendmapSize); // now to the ugly part float* ptr = blendmap->getBlendPointer(); for (Ogre::uint32 z = 0; z != blendmapSize; z++) { for (Ogre::uint32 x = 0; x != blendmapSize; x++) { Ogre::ColourValue c = img.getColourAt(x, z, 0); float alpha = bi.alpha; if (bi.blendMode == 'R') *ptr++ = c.r * alpha; else if (bi.blendMode == 'G') *ptr++ = c.g * alpha; else if (bi.blendMode == 'B') *ptr++ = c.b * alpha; else if (bi.blendMode == 'A') *ptr++ = c.a * alpha; } } blendmap->dirty(); blendmap->update(); } if (debugBlendMaps) { for (int i = 1; i < layerCount; i++) { Ogre::TerrainLayerBlendMap* blendMap = terrain->getLayerBlendMap(i); Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize(); Ogre::Image img; unsigned short *idata = OGRE_ALLOC_T(unsigned short, blendmapSize * blendmapSize, Ogre::MEMCATEGORY_RESOURCE); float scale = 65535.0f; for (unsigned int x = 0; x < blendmapSize; x++) for (unsigned int z = 0; z < blendmapSize; z++) idata[x + z * blendmapSize] = (unsigned short)(blendMap->getBlendValue(x, blendmapSize - z) * scale); img.loadDynamicImage((Ogre::uchar*)(idata), blendmapSize, blendmapSize, Ogre::PF_L16); std::string fileName = "blendmap_layer_" + Ogre::StringConverter::toString(i) + ".png"; img.save(fileName); OGRE_FREE(idata, Ogre::MEMCATEGORY_RESOURCE); } } }
void BrushSelector::buildPreviewBitmap( const Fairy::TextureInfo texInfo ) { const Ogre::uchar BytePerPixel = 8; // 读取原始image Ogre::Image *oriImage = GetSceneManipulator()->getPreviewImage(texInfo.ownerTextureName); // 源大纹理的大小 size_t oriImageHeight = oriImage->getHeight(); size_t oriImageWidth = oriImage->getWidth(); Ogre::uchar *oriImageData = oriImage->getData(); // 所选纹理的大小 size_t newImageWidth = texInfo.width*TexTileSize; size_t newImageHeight = texInfo.height*TexTileSize; // 分配一个足够大的空间来保存新建的image的数据 size_t newImagegetRowSpan = newImageWidth*oriImage->getBPP()/BytePerPixel; // 新建的image的行宽(单位为字节) Ogre::uchar *newImageData = OGRE_ALLOC_T(Ogre::uchar, oriImageHeight*newImagegetRowSpan, Ogre::MEMCATEGORY_GENERAL);//new Ogre::uchar[newImageHeight*newImagegetRowSpan]; Ogre::uchar *newImageDataPointer = newImageData; // 得知起始像素点 size_t startPoint = ( oriImageWidth * texInfo.topCorner + texInfo.leftCorner ) * TexTileSize * oriImage->getBPP()/BytePerPixel; Ogre::uchar *oriImagedataPointer = oriImageData + startPoint; // 把所选的纹理的数据提取出来,并创建一个新的image for ( Ogre::uint i=0; i<newImageHeight; ++i ) { memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan); newImageDataPointer += newImagegetRowSpan; oriImagedataPointer += oriImage->getRowSpan(); } Ogre::Image newImage; newImage.loadDynamicImage(newImageData,newImageWidth,newImageHeight,1,oriImage->getFormat(),true); // 如果所选纹理大于64*64,就先resize if ( texInfo.width > 1 || texInfo.height > 1 ) newImage.resize(mPreviewImageWidth, mPreviewImageHeight); // 如果有alpha,要与黑白图进行混合 if ( newImage.getHasAlpha() ) { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); float alphaValue = col.a; unsigned char r = col.r*255 * alphaValue + mBlackWhitePreviewImage.GetRed(i,j) * ( 1.0f - alphaValue); unsigned char g = col.g*255 * alphaValue + mBlackWhitePreviewImage.GetGreen(i,j) * ( 1.0f - alphaValue); unsigned char b = col.b*255 * alphaValue + mBlackWhitePreviewImage.GetBlue(i,j) * ( 1.0f - alphaValue); // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } // 设置到缩略图控件中 mBrushesPreview->SetBitmap(mCurrentPreviewImage); } // 没有alpha,就直接拷贝数据 else { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); unsigned char r = col.r*255; unsigned char g = col.g*255; unsigned char b = col.b*255; // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } mBrushesPreview->SetBitmap(mCurrentPreviewImage); } }
// ------------------------------------------------------------------------- void Terrain_Demo::init(Ogre::Root *root, Ogre::RenderWindow *win, OgreBulletApplication *application) { mCameraMove = 1; mHelpKeys.clear(); mHelpKeys.push_back(BASIC_HELP_INFO0); mHelpKeys.push_back(BASIC_HELP_INFO1); mHelpKeys.push_back(BASIC_HELP_INFO2); mHelpKeys.push_back(BASIC_HELP_INFO3); mHelpKeys.push_back(BASIC_HELP_INFO4); mHelpKeys.push_back(BASIC_HELP_INFO5); mHelpKeys.push_back(BASIC_HELP_INFO6); mHelpKeys.push_back("Use Arrow Key to move Car."); // reset for (int i = 0; i < 4; i++) { mWheelsEngine[i] = 0; mWheelsSteerable[i] = 0; } mWheelsEngineCount = 2; mWheelsEngine[0] = 0; mWheelsEngine[1] = 1; mWheelsEngine[2] = 2; mWheelsEngine[3] = 3; mWheelsSteerableCount = 2; mWheelsSteerable[0] = 0; mWheelsSteerable[1] = 1; //mWheelsSteerable[2] = 2; //mWheelsSteerable[3] = 3; mWheelEngineStyle = 0; mWheelSteeringStyle = 0; mSteeringLeft = false; mSteeringRight = false; mEngineForce = 0; mSteering = 0; // ------------------------ // Start OgreScene mSceneMgr = root->createSceneManager("TerrainSceneManager", "BulletTerrain"); mCamera = mSceneMgr->createCamera("Cam"); //mCamera->setFOVy(Degree(90)); mCamera->setNearClipDistance(0.1); mCamera->setFarClipDistance(1000); Viewport *vp = win->addViewport(mCamera); vp->setBackgroundColour(ColourValue(0,0,0)); // Alter the camera aspect ratio to match the viewport mCamera->setAspectRatio( Real(vp->getActualWidth()) / Real(vp->getActualHeight())); mCamera->setPosition(CameraStart + terrain_Shift); mCamera->lookAt(CarPosition + terrain_Shift); // Create a terrain std::string terrain_cfg("terrain.cfg"); mSceneMgr->setWorldGeometry(terrain_cfg); OgreBulletListener::init(root, win, application); // ------------------------ // add lights setBasicLight(); // ------------------------ // Add the Gui setPhysicGUI(); // ------------------------ // Start Bullet initWorld(); // ------------------------ // Add the ground // 0.1, 0.8 //addStaticPlane(0.3, 0.8); { Ogre::ConfigFile config; config.loadFromResourceSystem(terrain_cfg, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, "=", true); unsigned page_size = Ogre::StringConverter::parseUnsignedInt(config.getSetting("PageSize")); Ogre::Vector3 terrainScale(Ogre::StringConverter::parseReal(config.getSetting("PageWorldX")) / (page_size - 1), Ogre::StringConverter::parseReal(config.getSetting("MaxHeight")), Ogre::StringConverter::parseReal(config.getSetting("PageWorldZ")) / (page_size - 1)); Ogre::String terrainfileName = config.getSetting("Heightmap.image"); float *heights = new float[page_size*page_size]; Ogre::Image terrainHeightMap; terrainHeightMap.load(terrainfileName, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); for (unsigned y = 0; y < page_size; ++y) { for (unsigned x = 0; x < page_size; ++x) { Ogre::ColourValue color = terrainHeightMap.getColourAt(x, y, 0); heights[x + y * page_size] = color.r; } } mTerrainShape = new HeightmapCollisionShape(page_size, page_size, terrainScale, heights, true); RigidBody *defaultTerrainBody = new RigidBody("Terrain", mWorld); const float terrainBodyRestitution = 0.1f; const float terrainBodyFriction = 0.8f; Ogre::Vector3 terrainShiftPos( (terrainScale.x * (page_size - 1) / 2), \ 0, (terrainScale.z * (page_size - 1) / 2)); terrainShiftPos.y = terrainScale.y / 2 * terrainScale.y; Ogre::SceneNode* pTerrainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); defaultTerrainBody->setStaticShape (pTerrainNode, mTerrainShape, terrainBodyRestitution, terrainBodyFriction, terrainShiftPos); mBodies.push_back(defaultTerrainBody); mShapes.push_back(mTerrainShape); } // create obstacle in front of car addCube("obstacle", Ogre::Vector3(13, -5.25, -5) + terrain_Shift , Quaternion(Radian(Degree(22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(15, -5.25, -5) + terrain_Shift , Quaternion(Radian(Degree(22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(17, -5.25, -5) + terrain_Shift , Quaternion(Radian(Degree(22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(13, -5.25, -10) + terrain_Shift , Quaternion(Radian(Degree(-22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(15, -5.25, -10) + terrain_Shift , Quaternion(Radian(Degree(-22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(17, -5.25, -10) + terrain_Shift , Quaternion(Radian(Degree(-22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); // create obstacle a bit aside addCube("obstacle", Ogre::Vector3(-2, 0, -5) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(0, 0, -5) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(2, 0, -5) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(-2, 0, -10) + terrain_Shift , Quaternion(Radian(Degree(-45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(0, 0, -10) + terrain_Shift , Quaternion(Radian(Degree(-45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(2, 0, -10) + terrain_Shift , Quaternion(Radian(Degree(-45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); // create obstacle just for fun addCube("obstacle", Ogre::Vector3(25, -10, -25) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_Z), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(25, -10, -27) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_Z), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(25, -10, -29) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_Z), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); /// create vehicle { const Ogre::Vector3 chassisShift(0, 1.0, 0); float connectionHeight = 0.7f; mChassis = mSceneMgr->createEntity( "chassis" + StringConverter::toString(mNumEntitiesInstanced++), "chassis.mesh"); SceneNode *node = mSceneMgr->getRootSceneNode ()->createChildSceneNode (); SceneNode *chassisnode = node->createChildSceneNode (); chassisnode->attachObject (mChassis); chassisnode->setPosition (chassisShift); mChassis->setQueryFlags (GEOMETRY_QUERY_MASK); #if (OGRE_VERSION < ((1 << 16) | (5 << 8) | 0)) // only applicable before shoggoth (1.5.0) mChassis->setNormaliseNormals(true); #endif mChassis->setCastShadows(true); CompoundCollisionShape* compound = new CompoundCollisionShape(); BoxCollisionShape* chassisShape = new BoxCollisionShape(Ogre::Vector3(1.f,0.75f,2.1f)); compound->addChildShape(chassisShape, chassisShift); mCarChassis = new WheeledRigidBody("carChassis", mWorld); mCarChassis->setShape(node, compound, 0.6, //restitution 0.6, //friction 800, //bodyMass CarPosition + terrain_Shift, Quaternion::IDENTITY); mCarChassis->setDamping(0.2, 0.2); mCarChassis->disableDeactivation(); mTuning = new VehicleTuning(gSuspensionStiffness, gSuspensionCompression, gSuspensionDamping, gMaxSuspensionTravelCm, gMaxSuspensionForce, gFrictionSlip); mVehicleRayCaster = new VehicleRayCaster(mWorld); mVehicle = new RaycastVehicle(mCarChassis, mTuning, mVehicleRayCaster); { int rightIndex = 0; int upIndex = 1; int forwardIndex = 2; mVehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex); Ogre::Vector3 wheelDirectionCS0(0,-1,0); Ogre::Vector3 wheelAxleCS(-1,0,0); for (size_t i = 0; i < 4; i++) { mWheels[i] = mSceneMgr->createEntity( "wheel" + StringConverter::toString(mNumEntitiesInstanced++), "wheel.mesh"); mWheels[i]->setQueryFlags (GEOMETRY_QUERY_MASK); #if (OGRE_VERSION < ((1 << 16) | (5 << 8) | 0)) // only applicable before shoggoth (1.5.0) mWheels[i]->setNormaliseNormals(true); #endif mWheels[i]->setCastShadows(true); mWheelNodes[i] = mSceneMgr->getRootSceneNode ()->createChildSceneNode (); mWheelNodes[i]->attachObject (mWheels[i]); } { bool isFrontWheel = true; Ogre::Vector3 connectionPointCS0 ( CUBE_HALF_EXTENTS-(0.3*gWheelWidth), connectionHeight, 2*CUBE_HALF_EXTENTS-gWheelRadius); mVehicle->addWheel( mWheelNodes[0], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); connectionPointCS0 = Ogre::Vector3( -CUBE_HALF_EXTENTS+(0.3*gWheelWidth), connectionHeight, 2*CUBE_HALF_EXTENTS-gWheelRadius); mVehicle->addWheel( mWheelNodes[1], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); connectionPointCS0 = Ogre::Vector3( -CUBE_HALF_EXTENTS+(0.3*gWheelWidth), connectionHeight, -2*CUBE_HALF_EXTENTS+gWheelRadius); isFrontWheel = false; mVehicle->addWheel( mWheelNodes[2], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); connectionPointCS0 = Ogre::Vector3( CUBE_HALF_EXTENTS-(0.3*gWheelWidth), connectionHeight, -2*CUBE_HALF_EXTENTS+gWheelRadius); mVehicle->addWheel( mWheelNodes[3], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); //mVehicle->setWheelsAttached(); } } } }
void MaterialPreviewDialog::buildPreviewBitmap( const Ogre::String &texName ) { const Ogre::uchar BytePerPixel = 8; // 读取原始image Ogre::Image *oriImage = getPreviewImage(texName); // 源大纹理的大小 size_t oriImageHeight = oriImage->getHeight(); size_t oriImageWidth = oriImage->getWidth(); Ogre::uchar *oriImageData = oriImage->getData(); // 分配一个足够大的空间来保存新建的image的数据 size_t newImagegetRowSpan = oriImageWidth*oriImage->getBPP()/BytePerPixel; // 新建的image的行宽(单位为字节) Ogre::uchar *newImageData = OGRE_ALLOC_T(Ogre::uchar, oriImageHeight*newImagegetRowSpan, Ogre::MEMCATEGORY_GENERAL);//new Ogre::uchar[oriImageHeight*newImagegetRowSpan]; Ogre::uchar *newImageDataPointer = newImageData; Ogre::uchar *oriImagedataPointer = oriImageData; // 把所选的纹理的数据提取出来,并创建一个新的image for ( Ogre::uint i=0; i<oriImageHeight; ++i ) { memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan); newImageDataPointer += newImagegetRowSpan; oriImagedataPointer += oriImage->getRowSpan(); } Ogre::Image newImage; newImage.loadDynamicImage(newImageData,oriImageWidth,oriImageHeight,1,oriImage->getFormat(),true); // 如果所选纹理大于64*64,就先resize if ( oriImageWidth > mPreviewImageWidth || oriImageHeight > mPreviewImageHeight ) newImage.resize(mPreviewImageWidth, mPreviewImageHeight); // 如果有alpha,要与黑白图进行混合 if ( newImage.getHasAlpha() ) { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); float alphaValue = col.a; unsigned char r = col.r*255 * alphaValue; unsigned char g = col.g*255 * alphaValue; unsigned char b = col.b*255 * alphaValue; // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } } // 没有alpha,就直接拷贝数据 else { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); unsigned char r = col.r*255; unsigned char g = col.g*255; unsigned char b = col.b*255; // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } } }