Beispiel #1
0
void Scene::createBulletTerrain() {
	Ogre::Terrain* baseTerrain = mTerrainGroup->getTerrain(0, 0);
	btHeightfieldTerrainShape* hfShape = new btHeightfieldTerrainShape(
			baseTerrain->getSize(), baseTerrain->getSize(), baseTerrain->getHeightData(), 1, 0, 0,
			2, PHY_FLOAT, false);
	// Min and max height were set to 0 to force the terrain to be completely flat
	hfShape->setUseDiamondSubdivision(true);

	// This scale is based on the tutorial, but it may not be true...
	float metersBetweenVerts = baseTerrain->getWorldSize() / (baseTerrain->getSize() - 1);
	btVector3 scale(metersBetweenVerts, metersBetweenVerts, 1);
	hfShape->setLocalScaling(scale);

	hfShape->setUserPointer((void*) SU_Terrain);

	btCollisionObject* colObj = new btCollisionObject();
	colObj->setCollisionShape(hfShape);
	colObj->setFriction(0.9); colObj->setRestitution(0.0);
	colObj->setCollisionFlags(colObj->getCollisionFlags() |
							  btCollisionObject::CF_STATIC_OBJECT |
							  btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT);
	mSim->getCollisionWorld()->getDynamicsWorld()->addCollisionObject(colObj);
	mSim->getCollisionWorld()->addShape(hfShape);

	// Border planes
	const float px[4] = {-1, 1, 0, 0};
	const float py[4] = { 0, 0,-1, 1};
	for (int i = 0; i < 4; ++i) {
		btVector3 vpl(px[i], py[i], 0);
		btCollisionShape* shp = new btStaticPlaneShape(vpl, 0);
		shp->setUserPointer((void*) SU_Border);

		btTransform tr;  tr.setIdentity();
		tr.setOrigin(vpl * -0.5 * worldSize);

		btCollisionObject* col = new btCollisionObject();
		col->setCollisionShape(shp);
		col->setWorldTransform(tr);
		col->setFriction(0.3);   //+
		col->setRestitution(0.0);
		col->setCollisionFlags(col->getCollisionFlags() |
							   btCollisionObject::CF_STATIC_OBJECT |
							   btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT);

		mSim->getCollisionWorld()->getDynamicsWorld()->addCollisionObject(col);
		mSim->getCollisionWorld()->addShape(shp);
	}
}
void TerrainManager::CreatePhysicsShape(void)
{
    Ogre::TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
    while (ti.hasMoreElements())
    {
        Ogre::Terrain *t = ti.getNext()->instance;
        LoadTerrainGeometry(t->getMaterialName(), t->getHeightData(),
                            t->getSize(), t->getWorldSize(), t->getMinHeight(), t->getMaxHeight(), t->getPosition());
    }
}
Beispiel #3
0
void ManipulatorTerrain::OnEdit( float dt )
{
	assert(m_curEditMode != eTerrainEditMode_None);

	//第0层不能编辑BlendMap,应该从第1层开始
	if(m_curEditMode == eTerrainEditMode_Splat && m_curEditLayer == 0)
		return;

	Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain();

	const Vector3 brushPos = m_brush[m_curBrushIndex]->GetPosition();
	Vector3 tsPos;
	pTerrain->getTerrainPosition(brushPos, &tsPos);

	float brushSizeW, brushSizeH;
	m_brush[m_curBrushIndex]->GetDimension(brushSizeW, brushSizeH);
	float worldSize = GetWorldSize();
	brushSizeW /= worldSize;
	brushSizeH /= worldSize;

	int multiplier;
	Ogre::TerrainLayerBlendMap* layer = nullptr;
	if(m_curEditMode == eTerrainEditMode_Deform)
	{
		multiplier = pTerrain->getSize() - 1;
	}
	else
	{
		multiplier = pTerrain->getLayerBlendMapSize();
		layer = pTerrain->getLayerBlendMap(m_curEditLayer);
	}

	long startx = (long)((tsPos.x - brushSizeW / 2) * multiplier);
	long starty = (long)((tsPos.y - brushSizeH / 2) * multiplier);
	long endx = (long)((tsPos.x + brushSizeW / 2) * multiplier);
	long endy= (long)((tsPos.y + brushSizeH / 2) * multiplier);
	startx = max(startx, 0L);
	starty = max(starty, 0L);
	endx = min(endx, (long)multiplier);
	endy = min(endy, (long)multiplier);
	
	for (long y = starty; y <= endy; ++y)
	{
		for (long x = startx; x <= endx; ++x)
		{
			float tsXdist = (x / multiplier) - tsPos.x;
			float tsYdist = (y / multiplier)  - tsPos.y;

			if(m_curEditMode == eTerrainEditMode_Deform)
			{
				float* pData = pTerrain->getHeightData();
				pData[y*GetMapSize()+x] += 100.0f * dt;

			}
			else
			{
				float* pData = layer->getBlendPointer();
				size_t imgY = multiplier - y;
				float newValue = pData[imgY*multiplier+x] + dt;
				newValue = Ogre::Math::Clamp(newValue, 0.0f, 1.0f);
				pData[imgY*multiplier+x] = newValue;
			}
		}
	}
	
	
	if(m_curEditMode == eTerrainEditMode_Deform)
	{
		Ogre::Rect rect(startx, starty, endx, endy);
		pTerrain->dirtyRect(rect);
		pTerrain->update();
	}
	else
	{
		size_t imgStartY = multiplier - starty;
		size_t imgEndY = multiplier - endy;
		Ogre::Rect rect(startx, min(imgStartY,imgEndY), endx, max(imgStartY,imgEndY));

		layer->dirtyRect(rect);
		layer->update();
	}
}