void GeometryManager::_updateGeometry(Ogre::Camera* c, const Ogre::Real& timeSinceLastFrame) { // Look for current camera data std::vector<VClouds::CameraData>& camerasData = mVClouds->_getCamerasData(); std::vector<VClouds::CameraData>::iterator currentCameraDataIt; for (currentCameraDataIt = camerasData.begin(); currentCameraDataIt != camerasData.end(); currentCameraDataIt++) { if ((*currentCameraDataIt).camera == c) { break; } } std::vector<VClouds::CameraData>::reference currentCameraData = (*currentCameraDataIt); // Calculate wind offset Ogre::Vector2 CameraDirection = Ogre::Vector2(c->getDerivedDirection().x, c->getDerivedDirection().z); float offset = - CameraDirection.dotProduct(mVClouds->getWindDirectionV2()) * mVClouds->getWindSpeed() * timeSinceLastFrame; // Calculate camera offset Ogre::Vector2 CameraOffset = Ogre::Vector2(c->getDerivedPosition().x - currentCameraData.lastPosition.x, c->getDerivedPosition().z - currentCameraData.lastPosition.z); offset -= CameraOffset.dotProduct(CameraDirection); // Update camera data currentCameraData.cameraOffset += CameraOffset; currentCameraData.lastPosition = c->getDerivedPosition(); // Update geometry displacement currentCameraData.geometryDisplacement += Ogre::Vector3(offset); if (currentCameraData.geometryDisplacement.z < 0 || currentCameraData.geometryDisplacement.z > (mC-mB)/mNc) { currentCameraData.geometryDisplacement.z -= ((mC-mB)/mNc)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.z)/((mC-mB)/mNc)); } if (currentCameraData.geometryDisplacement.y < 0 || currentCameraData.geometryDisplacement.y > (mB-mA)/mNb) { currentCameraData.geometryDisplacement.y -= ((mB-mA)/mNb)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.y)/((mB-mA)/mNb)); } if (currentCameraData.geometryDisplacement.x < 0 || currentCameraData.geometryDisplacement.x > mA/mNa) { currentCameraData.geometryDisplacement.x -= (mA/mNa)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.x)/(mA/mNa)); } // Check under/over cloud rendering mCurrentDistance = c->getDerivedPosition()-mSceneNode->_getDerivedPosition(); for (int k = 0; k < mNumberOfBlocks; k++) { mGeometryBlocks.at(k)->setWorldOffset(mWorldOffset + currentCameraData.cameraOffset); mGeometryBlocks.at(k)->updateGeometry(c, currentCameraData.geometryDisplacement, mCurrentDistance); } }
void GeometryManager::_updateGeometry(const Ogre::Real& timeSinceLastFrame) { // Calculate wind offset Ogre::Vector2 CameraDirection = Ogre::Vector2(mVClouds->getCamera()->getDerivedDirection().x, mVClouds->getCamera()->getDerivedDirection().z); float offset = - CameraDirection.dotProduct(mVClouds->getWindDirectionV2()) * mVClouds->getWindSpeed() * timeSinceLastFrame; mWorldOffset += mVClouds->getWindDirectionV2() * mVClouds->getWindSpeed() * timeSinceLastFrame; // Calculate camera offset Ogre::Vector2 CameraOffset = Ogre::Vector2(mVClouds->getCamera()->getDerivedPosition().x - mLastCameraPosition.x, mVClouds->getCamera()->getDerivedPosition().z - mLastCameraPosition.z); offset -= CameraOffset.dotProduct(CameraDirection); mWorldOffset += CameraOffset; for (int k = 0; k < mNumberOfBlocks; k++) { mGeometryBlocks.at(k)->update(offset); mGeometryBlocks.at(k)->setWorldOffset(mWorldOffset); } }
//----------------------------------------------------------------------- void Triangulator::addConstraints(const Shape& shape, DelaunayTriangleBuffer& tbuffer) { std::vector<DelaunaySegment> segList; // Determine which segments should be added for (int i = 0; i<shape.getPoints().size()-1; i++) { bool isAlreadyIn = false; for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();it++) { if (it->containsSegment(i,i+1)) { isAlreadyIn = true; break; } } // only do something for segments not already in DT if (!isAlreadyIn) { segList.push_back(DelaunaySegment(i, i+1)); } } // Re-Triangulate according to the new segments for (std::vector<DelaunaySegment>::iterator it=segList.begin();it!=segList.end();it++) { // TODO remove all edges intersecting *it // TODO build two polygons // TODO Triangulate each polygon (directly into DelaunayTriangleBuffer) } // Clean up segments outside of shape if (shape.isClosed()) { for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();it++) { bool isTriangleOut = false; for (int i=0;i<3;i++) { int ind1 = it->i[i]; int ind2 = it->i[(1+i)%3]; // if side of triangle==segment, it won't tell us if outside or inside => skip if (abs(ind1-ind2)!=1) { Ogre::Vector2 v = shape.getPoint(ind2)-shape.getPoint(ind1); Ogre::Real d1 = v.dotProduct(shape.getNormalBefore(ind1)); Ogre::Real d2 = v.dotProduct(shape.getNormalAfter(ind1)); Ogre::Vector2 t1 = shape.getDirectionBefore(ind1); Ogre::Vector2 n1 = shape.getNormalAfter(ind1); if (t1.dotProduct(n1)>0.) { if (d1>0. || d2>0.) { isTriangleOut = true; break; } } else { if (d1>0. && d2>0.) { isTriangleOut = true; break; } } } } if (isTriangleOut) { it = tbuffer.erase(it); it--; } } } }