Real32 FrustumVolume::getScalarVolume() const { const Int32 faces[6][4] = { {0,1,3,2}, {4,5,7,6}, {0,4,5,1}, {2,6,7,3}, {2,6,4,0}, {1,5,7,3} }; Pnt3f vertices[8]; Line lines [4]; _planeVec[5].intersect(_planeVec[3], lines[3]); _planeVec[3].intersect(_planeVec[4], lines[2]); _planeVec[4].intersect(_planeVec[2], lines[0]); _planeVec[2].intersect(_planeVec[5], lines[1]); for(Int32 i = 0; i < 4; i++) { _planeVec[0].intersectInfinite(lines[i], vertices[ i]); _planeVec[1].intersectInfinite(lines[i], vertices[4 + i]); } Pnt3f center = Pnt3f(0.f, 0.f, 0.f); for(Int32 i = 0; i < 8; i++) { center = center + vertices[i].subZero(); } center /= 8.f; Real32 volume = .0f; for(Int32 i = 0; i < 6; i++) { Real32 height; Real32 area; height = _planeVec[i].getNormal().dot(center) - _planeVec[i].getDistanceFromOrigin(); Vec3f main_diag = vertices[faces[i][0]] - vertices[faces[i][2]]; Vec3f sec_diag = vertices[faces[i][1]] - vertices[faces[i][3]]; area = osgAbs((main_diag.cross(sec_diag)).length() / 2.f); volume += osgAbs((height*area)) / 3.f; } return volume; }
virtual void update(const UpdateEventUnrecPtr e) { ForceOnCharacter.setValues(0.0,0.0,0.0); Real32 PushForce(10000.0); Real32 Speed(20.0); if(_IsUpKeyDown) { ForceOnCharacter += Vec3f(0.0, PushForce, 0.0); } if(_IsDownKeyDown) { ForceOnCharacter += Vec3f(0.0, -PushForce, 0.0); } if(_IsLeftKeyDown) { ForceOnCharacter += Vec3f(-PushForce, 0.0, 0.0); } if(_IsRightKeyDown) { ForceOnCharacter += Vec3f(PushForce, 0.0, 0.0); } if(ForceOnCharacter != Vec3f(0.0,0.0,0.0)) { ShipBody->setEnable(true); } if(ForceOnCharacter.x() !=0.0) { ShipMotor->setFMax(osgAbs(ForceOnCharacter.x())); ShipMotor->setVel(osgSgn(ForceOnCharacter.x())*Speed); } else { ShipMotor->setFMax(0.0); ShipMotor->setVel(0.0); } if(ForceOnCharacter.y() !=0.0) { ShipMotor->setFMax2(osgAbs(ForceOnCharacter.y())); ShipMotor->setVel2(osgSgn(ForceOnCharacter.y())*Speed); } else { ShipMotor->setFMax2(0.0); ShipMotor->setVel2(0.0); } if(ForceOnCharacter.z() !=0.0) { ShipMotor->setFMax3(osgAbs(ForceOnCharacter.z())); ShipMotor->setVel3(osgSgn(ForceOnCharacter.z())*Speed); } else { ShipMotor->setFMax3(0.0); ShipMotor->setVel3(0.0); } }
Real32 OctreeAStarAlgorithm::manhattanDistanceCost(Octree::OTNodePtr node, const Pnt3f& Location, Real32 CostPerUnit) { Pnt3f Target; node->getVolume().getCenter(Target); return CostPerUnit * (osgAbs(Location.x() - Target.x()) + osgAbs(Location.y() - Target.y()) + osgAbs(Location.z() - Target.z())); }
Real32 DirectShowVideoWrapper::getAudioVolume(void) const { if(isInitialized()) { HRESULT hr; TCHAR szErr[MAX_ERROR_TEXT_LEN]; CComPtr<IBasicAudio> basicAudio; hr = _pGraphBuilder->QueryInterface(&basicAudio); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to get IBasicAudio, error: " << szErr << std::endl; return 0.0; } long Result; hr = basicAudio->get_Volume(&Result); if (FAILED(hr)) { AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); SWARNING << "Unable to get audio volume, error: " << szErr << std::endl; return 0.0; } return 1.0f - (osgAbs(static_cast<Real32>(Result))/10000.0f); } return 0.0; }
void ShaderShadowMapEngine::calcPointLightRange( const PointLight *pointL, Real32 lightThreshold, Real32 defaultNear, Real32 defaultFar, Real32 &outNear, Real32 &outFar ) { outNear = defaultNear; outFar = defaultFar; Real32 kQ = pointL->getQuadraticAttenuation(); Real32 kL = pointL->getLinearAttenuation (); Real32 kC = pointL->getConstantAttenuation (); if(osgAbs(kQ) > TypeTraits<Real32>::getDefaultEps()) { Real32 det = kL * kL - 4.f * kQ * (kC - 1.f / lightThreshold); if(det >= 0) { det = osgSqrt(det); Real32 r1 = - kL + det / (2.f * kQ); Real32 r2 = - kL - det / (2.f * kQ); if(r1 > 0.f && r2 > 0.f) { outFar = osgMin(r1, r2); } else if(r1 > 0.f) { outFar = r1; } else if(r2 > 0.f) { outFar = r2; } } } else if(osgAbs(kL) > TypeTraits<Real32>::getDefaultEps()) { Real32 r = (1.f / lightThreshold - kC) / kL; if(r > 0.f) { outFar = r; } } }
OSG_BASE_DLLMAPPING bool MatrixPerspective(OSG::Matrixr &result, OSG::Real rFovy, OSG::Real rAspect, OSG::Real rNear, OSG::Real rFar) { Real ct = osgTan(rFovy); bool error = false; if(rNear > rFar) { SWARNING << "MatrixPerspective: near " << rNear << " > far " << rFar << "!\n" << std::endl; error = true; } if(rFovy <= TypeTraits<Real>::getDefaultEps()) { SWARNING << "MatrixPerspective: fovy " << rFovy << " very small!\n" << std::endl; error = true; } if(osgAbs(rNear - rFar) < TypeTraits<Real>::getDefaultEps()) { SWARNING << "MatrixPerspective: near " << rNear << " ~= far " << rFar << "!\n" << std::endl; error = true; } if(rAspect < TypeTraits<Real>::getDefaultEps()) { SWARNING << "MatrixPerspective: aspect ratio " << rAspect << " very small!\n" << std::endl; error = true; } if(error) { result.setIdentity(); return true; } MatrixFrustum( result, -rNear * ct * rAspect, rNear * ct * rAspect, -rNear * ct, rNear * ct, rNear, rFar ); return false; }
bool SphereVolume::isOnSurface (const Pnt3f &point) const { if(osgAbs((point - _center).length() - _radius) < TypeTraits<Real32>::getDefaultEps()) { return true; } else { return false; } }
void FrameHandler::frame(Time frameTime) { if(_mfUninitializedFrameTasks.size() != 0) { this->init(); } setCurrTime(frameTime); if(osgAbs(_sfStartTime.getValue()) < 0.00001) { setStartTime(_sfCurrTime.getValue()); setLastTime(0.f); } _sfCurrTime.getValue() -= _sfStartTime.getValue(); if(_sfPaused.getValue() == false) { SFTime *pSFTimeStamp = editSFTimeStamp(); if(_sfConstantTime.getValue() == true) { pSFTimeStamp->getValue() += _sfConstantTimeStep.getValue(); if(pSFTimeStamp->getValue() < 0.) pSFTimeStamp->setValue(0.0); } else { pSFTimeStamp->getValue() += (_sfCurrTime.getValue() - _sfLastTime.getValue()) * _sfTimeScale.getValue(); if(pSFTimeStamp->getValue() < 0.) pSFTimeStamp->setValue(0.0); } } setLastTime(_sfCurrTime.getValue()); ++(editSFFrameCount()->getValue()); callTasks(); }
/*! Calculates the trapezoidal transformation matrix \a matNT that transforms post projection light space so that shadow map resolution in the "foreground" is maximized. The major steps are: - compute the intersection of eyeFrust and lightFrust - construct a trapezoid that contains the intersection - determine the transformation that maps this trapezoid to the (-1, 1) square Returns \c true if the transform was computed, \c false otherwise (e.g. if the intersection of eyeFrust and lightFrust is empty). For details see "T. Martin, T.-S. Tan: Anti-aliasing and Continuity with Trapezoidal Shadow Maps" */ bool TrapezoidalShadowMapEngine::calcTrapezoidalTransform( Matrixr &matNT, const Matrixr &matEyeToWorld, const Matrixr &matLightFull, const FrustumVolume &eyeFrust, const FrustumVolume &lightFrust ) { // obtain post proj. light space eye position Pnt3r eyePos; matEyeToWorld.mult (eyePos, eyePos); matLightFull .multFull(eyePos, eyePos); // intersect eye and light frusta, get vertices and center of intersection std::vector<Pnt3r> intVerts; Pnt3r intCenter; intersectFrusta(eyeFrust, lightFrust, intVerts, intCenter); if(intVerts.empty() == true) return false; // xform intCenter and intVerts to post proj. light space matLightFull.multFull(intCenter, intCenter); std::vector<Pnt3r>::iterator ivIt = intVerts.begin(); std::vector<Pnt3r>::iterator ivEnd = intVerts.end (); for(; ivIt != ivEnd; ++ivIt) matLightFull.multFull(*ivIt, *ivIt); Pnt2r eyePos2D (eyePos [0], eyePos [1]); Pnt2r intCenter2D(intCenter[0], intCenter[1]); // center line, normal, direction and distance from origin Vec2r clDir (intCenter2D - eyePos2D); clDir.normalize(); Vec2r clNorm(-clDir[1], clDir[0]); // distance of the center line from the origin Real clDist = clNorm.dot(eyePos2D.subZero()); // compute top and base lines: // - project intVerts onto the center line. // - top line is perpendicular to center line and goes through the // projected point closest to eyePos // - base line is perpendicular to center line and goes through the // projected point farthest from eyePos Pnt2r tlBase; Pnt2r blBase; Real topDist = TypeTraits<Real>::getMax(); Real baseDist = TypeTraits<Real>::getMin(); std::vector<Pnt3r>::const_iterator ivCIt = intVerts.begin(); std::vector<Pnt3r>::const_iterator ivCEnd = intVerts.end (); for(; ivCIt != ivCEnd; ++ivCIt) { Pnt2r ivPnt((*ivCIt)[0], (*ivCIt)[1]); ivPnt = ivPnt - (clNorm.dot(ivPnt) - clDist) * clNorm; Real dist = (ivPnt - eyePos2D).squareLength(); dist *= osgSgn(clDir.dot(ivPnt - eyePos2D)); if(dist < topDist) { topDist = dist; tlBase = ivPnt; } if(dist > baseDist) { baseDist = dist; blBase = ivPnt; } } topDist = osgSgn(topDist ) * osgSqrt(osgAbs(topDist )); baseDist = osgSgn(baseDist) * osgSqrt(osgAbs(baseDist)); // compute side lines: // - choose focusPnt (everything closer to the near plane is mapped to // 80% of the shadow map) - here we just take the point at 0.7 between // tlBase and blBase // - find a point (trapTip, q in the paper) on center line such that // focusPnt is mapped the 80% line in the shadow map // - choose lines through q that touch the convex hull of intVerts ivCIt = intVerts.begin(); ivCEnd = intVerts.end (); // Real centerDist = (intCenter2D - eyePos2D).length(); Real lambda = baseDist - topDist; Real delta = 0.5f * lambda; Real xi = -0.6f; Real eta = ((lambda * delta) + (lambda * delta * xi)) / (lambda - 2.f * delta - lambda * xi ); Pnt2r trapTip = tlBase - (eta * clDir); Pnt2r focusPnt = tlBase + (delta * clDir); // on both sides of the center line, find the point in intVerts that has // the smallest |cosine| (largest angle) between clDir and the vector // from trapTip to intVerts[i] Pnt2r posPnt; Real posCos = 1.f; Pnt2r negPnt; Real negCos = 1.f; for(UInt32 i = 0; ivCIt != ivCEnd; ++ivCIt, ++i) { Pnt2r ivPnt((*ivCIt)[0], (*ivCIt)[1]); Vec2r v = ivPnt - trapTip; v.normalize(); Real currCos = osgAbs(clDir.dot(v)); if(clNorm.dot(v) >= 0.f) { if(currCos <= posCos) { posPnt = ivPnt; posCos = currCos; } } else { if(currCos <= negCos) { negPnt = ivPnt; negCos = currCos; } } } // compute corners of trapezoid: Pnt2r trapVerts [4]; Pnt2r extraVerts[2]; Real posTan = osgTan(osgACos(posCos)); Real negTan = osgTan(osgACos(negCos)); trapVerts[0] = blBase - ((eta + lambda) * negTan * clNorm); trapVerts[1] = blBase + ((eta + lambda) * posTan * clNorm); trapVerts[2] = tlBase + ( eta * posTan * clNorm); trapVerts[3] = tlBase - ( eta * negTan * clNorm); extraVerts[0] = focusPnt + ((eta + delta) * posTan * clNorm); extraVerts[1] = focusPnt - ((eta + delta) * negTan * clNorm); // == xform trapezoid to unit square == // M1 = R * T1 -- translate center of top line to origin and rotate Vec2r u = 0.5f * (trapVerts[2].subZero() + trapVerts[3].subZero()); Vec2r v = trapVerts[3] - trapVerts[2]; v.normalize(); matNT.setValue( v[0], v[1], 0.f, -(u[0] * v[0] + u[1] * v[1]), -v[1], v[0], 0.f, (u[0] * v[1] - u[1] * v[0]), 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); // M2 = T2 * M1 -- translate tip to origin matNT[3][0] = - (matNT[0][0] * trapTip[0] + matNT[1][0] * trapTip[1]); matNT[3][1] = - (matNT[0][1] * trapTip[0] + matNT[1][1] * trapTip[1]); // M3 = H * M2 -- shear to make it symmetric wrt to the y axis // v = M2 * u v[0] = matNT[0][0] * u[0] + matNT[1][0] * u[1] + matNT[3][0]; v[1] = matNT[0][1] * u[0] + matNT[1][1] * u[1] + matNT[3][1]; Real a = - v[0] / v[1]; // matNT[*][0] : = mat[*][0] + a * mat[*][1] matNT[0][0] += a * matNT[0][1]; matNT[1][0] += a * matNT[1][1]; matNT[2][0] += a * matNT[2][1]; matNT[3][0] += a * matNT[3][1]; // M4 = S1 * M3 -- scale to make sidelines orthogonal and // top line is at y == 1 // v = 1 / (M3 * t2) v[0] = 1.f / (matNT[0][0] * trapVerts[2][0] + matNT[1][0] * trapVerts[2][1] + matNT[3][0]); v[1] = 1.f / (matNT[0][1] * trapVerts[2][0] + matNT[1][1] * trapVerts[2][1] + matNT[3][1]); matNT[0][0] *= v[0]; matNT[0][1] *= v[1]; matNT[1][0] *= v[0]; matNT[1][1] *= v[1]; matNT[2][0] *= v[0]; matNT[2][1] *= v[1]; matNT[3][0] *= v[0]; matNT[3][1] *= v[1]; // M5 = N * M4 -- turn trapezoid into rectangle matNT[0][3] = matNT[0][1]; matNT[1][3] = matNT[1][1]; matNT[2][3] = matNT[2][1]; matNT[3][3] = matNT[3][1]; matNT[3][1] += 1.f; // M6 = T3 * M5 -- translate center to origin // u = "M5 * t0" - only y and w coordinates // v = "M5 * t2" - only y and w coordinates u[0] = matNT[0][1] * trapVerts[0][0] + matNT[1][1] * trapVerts[0][1] + matNT[3][1]; u[1] = matNT[0][3] * trapVerts[0][0] + matNT[1][3] * trapVerts[0][1] + matNT[3][3]; v[0] = matNT[0][1] * trapVerts[2][0] + matNT[1][1] * trapVerts[2][1] + matNT[3][1]; v[1] = matNT[0][3] * trapVerts[2][0] + matNT[1][3] * trapVerts[2][1] + matNT[3][3]; a = - 0.5f * (u[0] / u[1] + v[0] / v[1]); matNT[0][1] += matNT[0][3] * a; matNT[1][1] += matNT[1][3] * a; matNT[2][1] += matNT[2][3] * a; matNT[3][1] += matNT[3][3] * a; // M7 = S2 * M6 -- scale to fill -1/+1 square // u = "M6 * t0" - only y and w coordinates u[0] = matNT[0][1] * trapVerts[0][0] + matNT[1][1] * trapVerts[0][1] + matNT[3][1]; u[1] = matNT[0][3] * trapVerts[0][0] + matNT[1][3] * trapVerts[0][1] + matNT[3][3]; a = -u[1] / u[0]; matNT[0][1] *= a; matNT[1][1] *= a; matNT[2][1] *= a; matNT[3][1] *= a; return true; }
void handleUpdate(UpdateEventDetails* const details, PhysicsBody* const CharacterPhysicsBody, PhysicsLMotorJoint* const CharacterMover) { ForceOnCharacter.setValues(0.0,0.0,0.0); Real32 PushForce(55000.0); Real32 Speed(10.0); if(_IsUpKeyDown) { ForceOnCharacter += Vec3f(0.0, PushForce, 0.0); } if(_IsDownKeyDown) { ForceOnCharacter += Vec3f(0.0, -PushForce, 0.0); } if(_IsLeftKeyDown) { ForceOnCharacter += Vec3f(-PushForce, 0.0, 0.0); } if(_IsRightKeyDown) { ForceOnCharacter += Vec3f(PushForce, 0.0, 0.0); } if(_ShouldJump) { ForceOnCharacter += Vec3f(0.0, 0.0, 50000.0); _ShouldJump = false; } if(ForceOnCharacter != Vec3f(0.0,0.0,0.0)) { CharacterPhysicsBody->setEnable(true); } if(ForceOnCharacter.x() !=0.0) { CharacterMover->setFMax(osgAbs(ForceOnCharacter.x())); CharacterMover->setVel(osgSgn(ForceOnCharacter.x())*Speed); } else { CharacterMover->setFMax(0.0); CharacterMover->setVel(0.0); } if(ForceOnCharacter.y() !=0.0) { CharacterMover->setFMax2(osgAbs(ForceOnCharacter.y())); CharacterMover->setVel2(osgSgn(ForceOnCharacter.y())*Speed); } else { CharacterMover->setFMax2(0.0); CharacterMover->setVel2(0.0); } if(ForceOnCharacter.z() !=0.0) { CharacterMover->setFMax3(osgAbs(ForceOnCharacter.z())); CharacterMover->setVel3(osgSgn(ForceOnCharacter.z())*Speed); } else { CharacterMover->setFMax3(0.0); CharacterMover->setVel3(0.0); } Real32 RotationRate(1.57); if(_IsAKeyDown) { Quaternion newRotation(CharacterPhysicsBody->getQuaternion()); newRotation.mult(Quaternion(Vec3f(0.0,0.0,1.0),RotationRate*details->getElapsedTime())); CharacterPhysicsBody->setQuaternion( newRotation ); } if(_IsDKeyDown) { Quaternion newRotation(CharacterPhysicsBody->getQuaternion()); newRotation.mult(Quaternion(Vec3f(0.0,0.0,1.0),-RotationRate*details->getElapsedTime())); CharacterPhysicsBody->setQuaternion( newRotation ); } }
void OgreMeshReader::verifyBoneAssignment(VertexElementStore &vertexElements, Int16 &boneIdxVE, Int16 &boneWeightVE ) { OSG_OGRE_LOG(("OgreMeshReader::verifyBoneAssignment\n")); GeoVec4fPropertyUnrecPtr boneIdxProp; GeoVec4fPropertyUnrecPtr boneWeightProp; if(boneIdxVE < 0) { SWARNING << "OgreMeshReader::verifyBoneAssignment: " << "Invalid bone index vertex element" << std::endl; return; } if(boneWeightVE < 0) { SWARNING << "OgreMeshReader::verifyBoneAssignment: " << "Invalid bone weight vertex element" << std::endl; return; } boneIdxProp = dynamic_pointer_cast<GeoVec4fProperty>(vertexElements[boneIdxVE ].prop); boneWeightProp = dynamic_pointer_cast<GeoVec4fProperty>(vertexElements[boneWeightVE].prop); GeoVec4fProperty::StoredFieldType* boneIdxF = boneIdxProp ->editFieldPtr(); GeoVec4fProperty::StoredFieldType* boneWeightF = boneWeightProp->editFieldPtr(); if(boneIdxF->size() != boneWeightF->size()) { SWARNING << "OgreMeshReader::verifyBoneAssignment: " << "Size mismatch between bone indices and weights." << std::endl; return; } for(UInt32 vertIdx = 0; vertIdx < boneIdxF->size(); ++vertIdx) { Real32 sumWeights = 0.f; Real32 numWeights = 0.f; for(UInt16 i = 0; i < 4; ++i) { if((*boneIdxF)[vertIdx][i] >= 0.f) { sumWeights += (*boneWeightF)[vertIdx][i]; numWeights += 1.f; } else { break; } } if(osgAbs(sumWeights - 1.f) > 1e-6f) { SWARNING << "OgreMeshReader::verifyBoneAssignment: " << "Vertex '" << vertIdx << "' influences not normalized," << " sumWeights " << sumWeights << " numWeights " << numWeights << std::endl; } } }
Vec3f CylinderDistribution3D::generate(void) const { Vec3f Result; switch(getSurfaceOrVolume()) { case SURFACE: { std::vector<Real32> Areas; //Min Cap Areas.push_back(0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius())); //Max Cap Areas.push_back(Areas.back() + 0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius())); //Inner Tube Areas.push_back(Areas.back() + getInnerRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight()); //Outer Tube Areas.push_back(Areas.back() + getOuterRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight()); bool HasTubeSides(osgAbs(getMaxTheta() - getMinTheta()) - 6.283185 < -0.000001); if(HasTubeSides) { //MinTheta Tube Side Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight()); //MaxTheta Tube Side Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight()); } Real32 PickEdge(RandomPoolManager::getRandomReal32(0.0,1.0)); if(PickEdge < Areas[0]/Areas.back()) { //Max Cap Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + (getHeight()/static_cast<Real32>(2.0))*getNormal(); } else if(PickEdge < Areas[1]/Areas.back()) { //Min Cap Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + (-getHeight()/static_cast<Real32>(2.0))*getNormal(); } else if(PickEdge < Areas[2]/Areas.back()) { //Inner Tube Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + getInnerRadius()*osgSin(Theta)*getTangent() + getInnerRadius()*osgCos(Theta)*getBinormal() + Height*getNormal(); } else if(PickEdge < Areas[3]/Areas.back()) { //Outer Tube Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + getOuterRadius()*osgSin(Theta)*getTangent() + getOuterRadius()*osgCos(Theta)*getBinormal() + Height*getNormal(); } else if(HasTubeSides && PickEdge < Areas[4]/Areas.back()) { //MinTheta Tube Side Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + (Radius*osgSin(getMinTheta()))*getTangent() + (Radius*osgCos(getMinTheta()))*getBinormal() + Height*getNormal(); } else if(HasTubeSides && PickEdge < Areas[5]/Areas.back()) { //MaxTheta Tube Side Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + (Radius*osgSin(getMaxTheta()))*getTangent() + (Radius*osgCos(getMaxTheta()))*getBinormal() + Height*getNormal(); } else { assert(false && "Should never reach this point"); } break; } case VOLUME: default: { //To get a uniform distribution across the disc get a uniformly distributed allong 0.0 - 1.0 //Then Take the square root of that. This gives a square root distribution from 0.0 - 1.0 //This square root distribution is used for the random radius because the area of a disc is //dependant on the square of the radius, i.e it is a quadratic function Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + Height*getNormal(); break; } } return Result; }
OSG_BASE_DLLMAPPING bool MatrixStereoPerspective(OSG::Matrixr &projection, OSG::Matrixr &projtrans, OSG::Real rFovy, OSG::Real rAspect, OSG::Real rNear, OSG::Real rFar, OSG::Real rZeroparallax, OSG::Real rEyedistance, OSG::Real rWhicheye, OSG::Real rOverlap) { Real rLeft; Real rRight; Real rTop; Real rBottom; Real gltan; Real rEye = -rEyedistance * (rWhicheye - .5f); Real d; bool error = false; if(rNear > rFar) { SWARNING << "MatrixPerspective: near " << rNear << " > far " << rFar << "!\n" << std::endl; error = true; } if(rFovy <= TypeTraits<Real>::getDefaultEps()) { SWARNING << "MatrixPerspective: fovy " << rFovy << " very small!\n" << std::endl; error = true; } if(osgAbs(rNear - rFar) < TypeTraits<Real>::getDefaultEps()) { SWARNING << "MatrixPerspective: near " << rNear << " ~= far " << rFar << "!\n" << std::endl; error = true; } if(rAspect < TypeTraits<Real>::getDefaultEps()) { SWARNING << "MatrixPerspective: aspect ratio " << rAspect << " very small!\n" << std::endl; error = true; } if(rZeroparallax < TypeTraits<Real>::getDefaultEps()) { SWARNING << "MatrixPerspective: zero parallax " << rZeroparallax << " very small, setting to 1!\n" << std::endl; rZeroparallax = 1.f; error = true; } if(error) { projection.setIdentity(); projtrans .setIdentity(); return true; } /* Calculate upper and lower clipping planes */ rTop = osgTan(rFovy / 2.0f) * rNear; rBottom = -rTop; /* Calculate left and right clipping planes */ gltan = osgTan(rFovy / 2.0f) * rAspect; rLeft = (-gltan + rEye / rZeroparallax) * rNear; rRight = ( gltan + rEye / rZeroparallax) * rNear; d = rRight - rLeft; rLeft += d * (1.f - rOverlap) * (rWhicheye - .5f); rRight += d * (1.f - rOverlap) * (rWhicheye - .5f); MatrixFrustum(projection, rLeft, rRight, rBottom, rTop, rNear, rFar); projtrans.setIdentity(); projtrans[3][0] = rEye; return false; }
Real32 dist3D_Segment_to_Segment(const Pnt3f& s1p, const Vec3f& s1d, const Pnt3f& s2p, const Vec3f& s2d) { const float SMALL_NUM = 1e-9f; // anything that avoids division overflow const Vec3f& u = s1d; const Vec3f& v = s2d; Vec3f w = s1p - s2p; Real32 a = u.dot(u); // always >= 0 Real32 b = u.dot(v); Real32 c = v.dot(v); // always >= 0 Real32 d = u.dot(w); Real32 e = v.dot(w); Real32 D = a*c - b*b; // always >= 0 Real32 sc, sN, sD = D; // sc = sN / sD, default sD = D >= 0 Real32 tc, tN, tD = D; // tc = tN / tD, default tD = D >= 0 // compute the line parameters of the two closest points if(D < SMALL_NUM) // the lines are almost parallel { sN = 0.0f; // force using point P0 on segment S1 sD = 1.0f; // to prevent possible division by 0.0 later tN = e; tD = c; } else // get the closest points on the infinite lines { sN = (b*e - c*d); tN = (a*e - b*d); if(sN < 0.0f) // sc < 0 => the s=0 edge is visible { sN = 0.0f; tN = e; tD = c; } else if (sN > sD) // sc > 1 => the s=1 edge is visible { sN = sD; tN = e + b; tD = c; } } if(tN < 0.0f) // tc < 0 => the t=0 edge is visible { tN = 0.0f; // recompute sc for this edge if(-d < 0.0f) { sN = 0.0f; } else if(-d > a) { sN = sD; } else { sN = -d; sD = a; } } else if (tN > tD) // tc > 1 => the t=1 edge is visible { tN = tD; // recompute sc for this edge if((-d + b) < 0.0f) { sN = 0.f; } else if ((-d + b) > a) { sN = sD; } else { sN = (-d + b); sD = a; } } // finally do the division to get sc and tc sc = (osgAbs(sN) < SMALL_NUM ? 0.0f : sN / sD); tc = (osgAbs(tN) < SMALL_NUM ? 0.0f : tN / tD); // get the difference of the two closest points Vec3f dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc) return dP.length(); // return the squared distance }
void ComplexSceneManager::frame(void) { #if 0 setCurrTime(getSystemTime()); if(osgAbs(_sfStartTime.getValue()) < 0.00001) { setStartTime(_sfCurrTime.getValue()); setLastTime(0.f); } _sfCurrTime.getValue() -= _sfStartTime.getValue(); if(_sfPaused.getValue() == false) { SFTime *pSFTimeStamp = editSFTimeStamp(); if(_sfConstantTime.getValue() == true) { pSFTimeStamp->getValue() += _sfConstantTimeStep.getValue(); if(pSFTimeStamp->getValue() < 0.) pSFTimeStamp->setValue(0.0); } else { pSFTimeStamp->getValue() += (_sfCurrTime.getValue() - _sfLastTime.getValue()) * _sfTimeScale.getValue(); if(pSFTimeStamp->getValue() < 0.) pSFTimeStamp->setValue(0.0); } } setLastTime(_sfCurrTime.getValue()); SystemTime = _sfTimeStamp.getValue(); ++(editSFFrameCount()->getValue()); if(_sfSensorTask.getValue() != NULL) { _sfSensorTask.getValue()->frame(_sfTimeStamp.getValue (), _sfFrameCount.getValue()); } #endif if(_sfDumpFrameStart.getValue() == true) { fprintf(stderr, "=================================================\n"); fprintf(stderr, "Render Frame\n"); fprintf(stderr, "=================================================\n"); } FrameHandler::the()->frame(); SystemTime = FrameHandler::the()->getTimeStamp(); commitChanges(); if(_sfDrawManager.getValue() != NULL) { _sfDrawManager.getValue()->frame(FrameHandler::the()->getTimeStamp(), FrameHandler::the()->getFrameCount()); } }
void Trackball::updateRotation(Real32 rLastX, Real32 rLastY, Real32 rCurrentX, Real32 rCurrentY) { Quaternion qCurrVal; Vec3f gAxis; /* Axis of rotation */ Real32 rPhi = 0.f; /* how much to rotate about axis */ Vec3f gP1; Vec3f gP2; Vec3f gDiff; Real32 rTmp; if( (osgAbs(rLastX - rCurrentX) > TypeTraits<Real32>::getDefaultEps()) || (osgAbs(rLastY - rCurrentY) > TypeTraits<Real32>::getDefaultEps()) ) { /* * First, figure out z-coordinates for projection of P1 and P2 to * deformed sphere */ gP1.setValues( rLastX, rLastY, projectToSphere(_rTrackballSize, rLastX, rLastY)); gP2.setValues( rCurrentX, rCurrentY, projectToSphere(_rTrackballSize, rCurrentX, rCurrentY)); /* * Now, we want the cross product of P1 and P2 */ gAxis = gP2; gAxis.crossThis(gP1); /* * Figure out how much to rotate around that axis. */ gDiff = gP2; gDiff -= gP1; rTmp = gDiff.length() / (2.0f * _rTrackballSize); /* * Avoid problems with out-of-control values... */ if(rTmp > 1.0) rTmp = 1.0; if(rTmp < -1.0) rTmp = -1.0; if(_gMode == OSGObject) rPhi = Real32(-2.0) * osgASin(rTmp); else rPhi = Real32( 2.0) * osgASin(rTmp); } rPhi *= _rRotScale; if(_bSum == false) { _qVal.setValueAsAxisRad(gAxis, rPhi); } else { qCurrVal.setValueAsAxisRad(gAxis, rPhi); _qVal *= qCurrVal; // _qVal.multLeft(qCurrVal); } }
void MorphGeometry::updateMorph(void) { if(!getBaseGeometry()) { SWARNING << "No Base Geometry" << std::endl; return; } for(UInt32 i(0) ; i<getMFMorphProperties()->size() ; ++i) { GeoVectorProperty* BaseProp(getBaseGeometry()->getProperty(getMorphProperties(i))); GeoVectorPropertyUnrecPtr Prop(getProperty(getMorphProperties(i))); switch(getBlendingMethod()) { case Relative: { //Reset the Base mesh UInt32 NumBytesToCopy(Prop->getFormatSize() * BaseProp->size() * BaseProp->getDimension()); memcpy(Prop->editData(), BaseProp->getData(), NumBytesToCopy); } break; default: SWARNING << "Invalid blending method: " << getBlendingMethod() << ". Using Normalized method." << std::endl; case Normalized: { Real32 Weight(1.0f); for(UInt32 j(0) ; j < getNumMorphTargets() ; ++j) { Weight -= osgAbs(getMorphTargetWeight(j)); } //Zero out the property zeroGeoProperty(Prop); //Call the morph property with the given property format morphGeoProperty(BaseProp, Prop, Weight); } break; } setProperty(Prop, getMorphProperties(i)); //Loop through all morph targets Geometry* Target; GeoVectorProperty* TargetProp; Real32 Weight; for(UInt32 j(0) ; j < getNumMorphTargets() ; ++j) { //If the Weight is really small then don't apply it Weight = osgAbs(getMorphTargetWeight(j)); if(Weight < 0.000001f) { continue; } Target = getMorphTarget(j); TargetProp = Target->getProperty(getMorphProperties(i)); //Call the morph property with the given property format morphGeoProperty(TargetProp, Prop, Weight); } } }
void TextureBackground::clear(DrawEnv *pEnv) { #if !defined(OSG_OGL_COREONLY) || defined(OSG_CHECK_COREONLY) TextureBaseChunk *tex = getTexture(); if(tex == NULL) { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); return; } glPushAttrib(GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT); glDisable(GL_LIGHTING); #if 1 // original mode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #else // for testing the grid glColor3f(1.0f, 1.0f, 1.0f); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #endif glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); glDepthMask(GL_FALSE); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, 1, 0, 1, 0, 1); glColor4fv(getColor().getValuesRGBA()); tex->activate(pEnv); if(tex->isTransparent()) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } if(osgAbs(getRadialDistortion()) < TypeTraits<Real32>::getDefaultEps()) { if(getMFTexCoords()->size() < 4) { // set some default texture coordinates. glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 1.0f, 0.0f); glEnd(); } else { glBegin(GL_QUADS); { glTexCoord2f(getTexCoords(0).getValues()[0], getTexCoords(0).getValues()[1]); glVertex3f(0.0f, 0.0f, 0.0f); glTexCoord2f(getTexCoords(1).getValues()[0], getTexCoords(1).getValues()[1]); glVertex3f(1.0f, 0.0f, 0.0f); glTexCoord2f(getTexCoords(2).getValues()[0], getTexCoords(2).getValues()[1]); glVertex3f(1.0f, 1.0f, 0.0f); glTexCoord2f(getTexCoords(3).getValues()[0], getTexCoords(3).getValues()[1]); glVertex3f(0.0f, 1.0f, 0.0f); } glEnd(); } } else // map texture to distortion grid { updateGrid(); Int16 xxmax=getHor()+2,yymax=getVert()+2; UInt32 gridCoords=xxmax*yymax; UInt32 indexArraySize=xxmax*((getVert()+1)*2); if(_vertexCoordArray.size()==gridCoords && _textureCoordArray.size()==gridCoords && _indexArray.size()==indexArraySize) { // clear background, because possibly the distortion grid // could not cover th whole window glClearColor(.5f, 0.5f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); std::vector<UInt32>::iterator i; UInt32 yMax=getVert()+1; for(UInt32 y=0;y<yMax;y++) { glBegin(GL_TRIANGLE_STRIP); std::vector<UInt32>::iterator begin=_indexArray.begin()+(y*2*xxmax); std::vector<UInt32>::iterator end=begin+2*xxmax; for(std::vector<UInt32>::iterator i=begin;i!=end;i++) { glTexCoord2fv(_textureCoordArray[*i].getValues()); glVertex2fv(_vertexCoordArray[*i].getValues()); } glEnd(); } } } if(tex->isTransparent()) { glDisable(GL_BLEND); } tex->deactivate(pEnv); Int32 bit = getClearStencilBit(); if (bit >= 0) { glClearStencil(bit); glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } else { glClear(GL_DEPTH_BUFFER_BIT); } glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); glColor3f(1.0f, 1.0f, 1.0f); #endif }
void PhysicsSpace::collisionCallback (dGeomID o1, dGeomID o2) { StatRealElem *NCollisionTestsStatElem = StatCollector::getGlobalElem(PhysicsHandler::statNCollisionTests); if(NCollisionTestsStatElem) { NCollisionTestsStatElem->add(1.0f); } if (dGeomIsSpace (o1) || dGeomIsSpace (o2)) { // colliding a space with something dSpaceCollide2 (o1,o2,reinterpret_cast<void *>(this),&PhysicsSpace::collisionCallback); // collide all geoms internal to the space(s) if (dGeomIsSpace (o1)) dSpaceCollide (dGeomGetSpace(o1),reinterpret_cast<void *>(this),&PhysicsSpace::collisionCallback); if (dGeomIsSpace (o2)) dSpaceCollide (dGeomGetSpace(o2),reinterpret_cast<void *>(this),&PhysicsSpace::collisionCallback); } else { _DiscardCollision = false; // colliding two non-space geoms, so generate contact // points between o1 and o2 Int32 numContacts = dCollide(o1, o2, _ContactJoints.size(), &(_ContactJoints[0].geom), sizeof(dContact)); StatRealElem *NCollisionsStatElem = StatCollector::getGlobalElem(PhysicsHandler::statNCollisions); if(NCollisionsStatElem) { NCollisionsStatElem->add(static_cast<Real32>(numContacts)); } if(numContacts>0) { Vec3f v1,v2,normal; Pnt3f position; dVector3 odeVec; Real32 projectedNormalSpeed; for (Int32 i=0; i < numContacts; i++) { normal += Vec3f(&_ContactJoints[i].geom.normal[0]); position += Vec3f(&_ContactJoints[i].geom.pos[0]); if(dGeomGetBody(o1)) { dBodyGetPointVel(dGeomGetBody(o1), _ContactJoints[i].geom.pos[0], _ContactJoints[i].geom.pos[1], _ContactJoints[i].geom.pos[2],odeVec); v1 += Vec3f(&odeVec[0]); } if(dGeomGetBody(o2)) { dBodyGetPointVel(dGeomGetBody(o2), _ContactJoints[i].geom.pos[0], _ContactJoints[i].geom.pos[1], _ContactJoints[i].geom.pos[2],odeVec); v2 += Vec3f(&odeVec[0]); } } normal = normal * (1.0f/static_cast<Real32>(numContacts)); position = position * (1.0f/static_cast<Real32>(numContacts)); v1 = v1 * (1.0f/static_cast<Real32>(numContacts)); v2 = v2 * (1.0f/static_cast<Real32>(numContacts)); projectedNormalSpeed = (v1+v2).projectTo(normal); //TODO: Add a way to get the PhysicsGeomUnrecPtr from the GeomIDs so that the PhysicsGeomUnrecPtr can be //sent to the collision event produceCollision(position, normal, NULL, NULL, dGeomGetCategoryBits(o1), dGeomGetCollideBits (o1), dGeomGetCategoryBits(o2), dGeomGetCollideBits (o2), v1, v2, osgAbs(projectedNormalSpeed)); UInt32 Index(0); for(; Index<_CollisionListenParamsVec.size() ; ++Index) { if((dGeomGetCategoryBits(o1) & _CollisionListenParamsVec[Index]._Category) || (dGeomGetCategoryBits(o2) & _CollisionListenParamsVec[Index]._Category)) { break; } } if(Index < _CollisionListenParamsVec.size()) { for(UInt32 i(0); i<_CollisionListenParamsVec.size() ; ++i) { if( ((dGeomGetCategoryBits(o1) & _CollisionListenParamsVec[i]._Category) || (dGeomGetCategoryBits(o2) & _CollisionListenParamsVec[i]._Category)) && (osgAbs(projectedNormalSpeed) >= _CollisionListenParamsVec[i]._SpeedThreshold) ) { //TODO: Add a way to get the PhysicsGeomUnrecPtr from the GeomIDs so that the PhysicsGeomUnrecPtr can be //sent to the collision event produceCollision(_CollisionListenParamsVec[i]._Listener, position, normal, NULL, NULL, dGeomGetCategoryBits(o1), dGeomGetCollideBits (o1), dGeomGetCategoryBits(o2), dGeomGetCollideBits (o2), v1, v2, osgAbs(projectedNormalSpeed)); } } } } if(!_DiscardCollision) { // add these contact points to the simulation for (Int32 i=0; i < numContacts; i++) { getCollisionContact(dGeomGetCategoryBits(o1), dGeomGetCategoryBits(o2))->updateODEContactJoint(_ContactJoints[i]); dJointID jointId = dJointCreateContact(_CollideWorldID, _ColJointGroupId, &_ContactJoints[i]); dJointAttach(jointId, dGeomGetBody(o1), dGeomGetBody(o2)); } } } }
bool Line::intersect(const CylinderVolume &cyl, Real &enter, Real &exit ) const { Real radius = cyl.getRadius(); Vec3r adir; Vec3r o_adir; Pnt3r apos; cyl.getAxis(apos, adir); o_adir = adir; adir.normalize(); bool isect; Real ln; Real dl; Vec3r RC; Vec3r n; Vec3r D; RC = _pos - apos; n = _dir.cross (adir); ln = n .length( ); if(ln == 0.f) // IntersectionLine is parallel to CylinderAxis { D = RC - (RC.dot(adir)) * adir; dl = D.length(); if(dl <= radius) // line lies in cylinder { enter = 0.f; exit = Inf; } else { return false; } } else { n.normalize(); dl = osgAbs(RC.dot(n)); //shortest distance isect = (dl <= radius); if(isect) { // if ray hits cylinder Real t; Real s; Vec3r O; O = RC.cross(adir); t = - (O.dot(n)) / ln; O = n.cross(adir); O.normalize(); s = osgAbs ( (osgSqrt ((radius * radius) - (dl * dl))) / (_dir.dot(O))); exit = t + s; if(exit < 0.f) return false; enter = t - s; if(enter < 0.f) enter = 0.f; } else { return false; } } Real t; Plane bottom(-adir, apos); if(bottom.intersect(*this, t)) { if(bottom.isInHalfSpace(_pos)) { if(t > enter) enter = t; } else { if(t < exit) exit = t; } } else { if(bottom.isInHalfSpace(_pos)) return false; } Plane top(adir, apos + o_adir); if(top.intersect(*this, t)) { if(top.isInHalfSpace(_pos)) { if(t > enter) enter = t; } else { if(t < exit) exit = t; } } else { if(top.isInHalfSpace(_pos)) return false; } return (enter < exit); }