void TerrainGenerator::raise(float x, float z, float scale) { float cols = _heightField->getColumnCount(); float rows = _heightField->getRowCount(); float *usedHeights = _heightField->getArray(); unsigned int i, j, repeats; GP_ASSERT(cols > 0); GP_ASSERT(rows > 0); // Since the specified coordinates are in world space, we need to use the // inverse of our world matrix to transform the world x,z coords back into // local heightfield coordinates for indexing into the height array. Vector3 v = getInverseWorldMatrix() * Vector3(x, 0.0f, z); Vector3 s = getInverseWorldMatrix() * Vector3(scale, 0.0f, 0.0f); float localx = v.x + (cols - 1) * 0.5f; float localz = v.z + (rows - 1) * 0.5f; float localscale = s.x; for (i = 0; i < _heightFieldSize; i++) { for (j = 0; j < _heightFieldSize; j++) { float dist = this->distanceFromCenter((float)i, (float)j, localx, localz); float strength = localscale - dist; if (strength > 0) { usedHeights[i + (j * _heightFieldSize)] += strength; } } } //this->smooth(x, z, scale); this->updateTerrain(); }
//----------------------------------------------------------------------------- const Vector4& AutoParamDataSource::getCameraPositionObjectSpace(void) const { if (mCameraPositionObjectSpaceDirty) { if (mCameraRelativeRendering) { mCameraPositionObjectSpace = Vector4(getInverseWorldMatrix() * Vector3::ZERO); } else { mCameraPositionObjectSpace = Vector4(getInverseWorldMatrix() * mCurrentCamera->getDerivedPosition()); } mCameraPositionObjectSpaceDirty = false; } return mCameraPositionObjectSpace; }
//----------------------------------------------------------------------------- const Matrix4& AutoParamDataSource::getInverseTransposeWorldMatrix(void) const { if (mInverseTransposeWorldMatrixDirty) { mInverseTransposeWorldMatrix = getInverseWorldMatrix().transpose(); mInverseTransposeWorldMatrixDirty = false; } return mInverseTransposeWorldMatrix; }
//----------------------------------------------------------------------------- const Vector4& AutoParamDataSource::getLodCameraPositionObjectSpace(void) const { if (mLodCameraPositionObjectSpaceDirty) { if (mCameraRelativeRendering) { mLodCameraPositionObjectSpace = getInverseWorldMatrix().transformAffine(mCurrentCamera->getLodCamera()->getDerivedPosition() - mCameraRelativePosition); } else { mLodCameraPositionObjectSpace = getInverseWorldMatrix().transformAffine(mCurrentCamera->getLodCamera()->getDerivedPosition()); } mLodCameraPositionObjectSpaceDirty = false; } return mLodCameraPositionObjectSpace; }
//----------------------------------------------------------------------------- Real AutoParamDataSource::getShadowExtrusionDistance(void) const { const Light& l = getLight(0); // only ever applies to one light at once if (l.getType() == Light::LT_DIRECTIONAL) { // use constant return mDirLightExtrusionDistance; } else { // Calculate based on object space light distance // compared to light attenuation range Vector3 objPos = getInverseWorldMatrix().transformAffine(l.getDerivedPosition(true)); return l.getAttenuationRange() - objPos.length(); } }
void TerrainGenerator::smooth(float x, float z, float scale) { float cols = _heightField->getColumnCount(); float rows = _heightField->getRowCount(); float *usedHeights = _heightField->getArray(); unsigned int i, j, repeats; unsigned int iminus, iplus, jminus, jplus; GP_ASSERT(cols > 0); GP_ASSERT(rows > 0); // Since the specified coordinates are in world space, we need to use the // inverse of our world matrix to transform the world x,z coords back into // local heightfield coordinates for indexing into the height array. Vector3 v = getInverseWorldMatrix() * Vector3(x, 0.0f, z); Vector3 s = getInverseWorldMatrix() * Vector3(scale, 0.0f, 0.0f); float localx = v.x + (cols - 1) * 0.5f; float localz = v.z + (rows - 1) * 0.5f; float localscale = s.x; for (repeats = 0; repeats < 2; repeats++) { for (i = 0; i < _heightFieldSize; i++) { for (j = 0; j < _heightFieldSize; j++) { float dist = this->distanceFromCenter((float)i, (float)j, localx, localz); float strength = localscale - dist; if (strength > 0) { iminus = i - 1; iplus = i + 1; jminus = j - 1; jplus = j + 1; if (iminus >= _heightFieldSize) { iminus = 0; } if (jminus >= _heightFieldSize) { jminus = 0; } if (iplus >= _heightFieldSize) { iplus = _heightFieldSize - 1; } if (jplus > _heightFieldSize) { jplus = _heightFieldSize - 1; } usedHeights[i + (j * _heightFieldSize)] = (usedHeights[iminus + (jminus * _heightFieldSize)] + usedHeights[i + (jminus * _heightFieldSize)] + usedHeights[iplus + (jminus * _heightFieldSize)] + usedHeights[iminus + (j * _heightFieldSize)] + usedHeights[i + (j * _heightFieldSize)] + usedHeights[iplus + (j * _heightFieldSize)] + usedHeights[iminus + (jplus * _heightFieldSize)] + usedHeights[i + (jplus * _heightFieldSize)] + usedHeights[iplus + (jplus * _heightFieldSize)]) / 9.0f; } } } } this->updateTerrain(); }