bool PCZFrustum::isVisible( const Sphere & bound) const { // Check originplane if told to if (mUseOriginPlane) { Plane::Side side = mOriginPlane.getSide(bound.getCenter()); if (side == Plane::NEGATIVE_SIDE) { Real dist = mOriginPlane.getDistance(bound.getCenter()); if (dist > bound.getRadius()) { return false; } } } // For each extra active culling plane, see if the entire sphere is on the negative side // If so, object is not visible PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); while ( pit != mActiveCullingPlanes.end() ) { PCPlane * plane = *pit; Plane::Side xside = plane->getSide(bound.getCenter()); if (xside == Plane::NEGATIVE_SIDE) { Real dist = plane->getDistance(bound.getCenter()); if (dist > bound.getRadius()) { return false; } } pit++; } return true; }
static T find( const Sphere< T > &sphere, const Ray< 3, T > &ray, T lowerBound = Numeric< T >::ZERO_TOLERANCE, T upperBound = std::numeric_limits< T >::max() ) { Vector< 3, T > centerDiff( ray.getOrigin() - sphere.getCenter() ); T a = ray.getDirection().getSquaredMagnitude(); T b = 2 * ( centerDiff * ray.getDirection() ); T c = centerDiff.getSquaredMagnitude() - ( sphere.getRadius() * sphere.getRadius() ); T t0, t1; if ( Root::compute( a, b, c, t0, t1 ) == 0 ) { return -1; } if ( t0 < upperBound && t0 > lowerBound ) { return t0; } if ( t1 < upperBound && t1 > lowerBound ) { return t1; } return -1; }
/* special function that returns true only when sphere fully fits inside the frustum. */ bool PCZFrustum::isFullyVisible(const Sphere& bound) const { // Check originplane if told to if (mUseOriginPlane) { if (mOriginPlane.getDistance(bound.getCenter()) <= bound.getRadius() || mOriginPlane.getSide(bound.getCenter()) != Plane::POSITIVE_SIDE) { return false; } } // For each extra active culling plane, // see if the sphere is not on the positive side // If so, object is not fully visible PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); while ( pit != mActiveCullingPlanes.end() ) { PCPlane* plane = *pit; if (plane->getDistance(bound.getCenter()) <= bound.getRadius() || plane->getSide(bound.getCenter()) != Plane::POSITIVE_SIDE) { return false; } pit++; } return true; }
bool TestSpherePoly ( Sphere const & A, VertexList const & verts, Plane3d const & P ) { if(!TestSpherePlane(A,P)) return false; float dist2 = Distance3d::Distance2PointPoly(A.getCenter(),verts); return dist2 < (A.getRadius() * A.getRadius()); }
ContainmentResult TestPointSphere ( Vector const & V, Sphere const & S ) { real radiusSquared = S.getRadius() * S.getRadius(); real distanceSquared = (V-S.getCenter()).magnitudeSquared(); return Containment1d::TestFloatLess(distanceSquared,radiusSquared); }
static void View(Camera* camera, const AxisAlignedBox& aabb, const Sphere& sphere) { float nearClip = (sphere.getRadius() > 1)? 1 : 0.05; float farClip = sphere.getRadius()*10000.0f; camera->setNearClipDistance(nearClip); camera->setFarClipDistance(farClip); // tan (fov/2.0) = r/d => d = r/tan(fov/2.0) float distance = sphere.getRadius()/Math::Tan(camera->getFOVy()/2.0f); camera->setPosition(sphere.getCenter() - (camera->getDirection().normalisedCopy()*distance)); }
//============================================================================== Sphere Sphere::getCompoundShape(const Sphere& b) const { const Sphere& a = *this; /// TODO test this /* Vec3 centerDiff = b.center - a.center; F32 radiusDiff = b.radius - a.radius; Vec3 radiusDiffSqr = radiusDiff * radiusDiff; F32 lenSqr = centerDiff.getLengthSquared(); if(radiusDiffSqrt >= 0.0) { if(radiusDiff >= 0.0) { return b; } else { return a; } } else { F32 l = sqrt(lenSqr); F32 t = (l + b.radius - a.radius) / (2.0 * l); return Sphere(a.center + t * centerDiff, (l + a.radius + b.radius) / 2.0); } */ Vec4 c = b.getCenter() - a.getCenter(); // Vector from one center to the // other F32 cLen = c.getLength(); if(cLen + b.getRadius() < a.getRadius()) { return a; } else if(cLen + a.getRadius() < b.getRadius()) { return b; } Vec4 bnorm = c / cLen; Vec4 ca = (-bnorm) * a.getRadius() + a.getCenter(); Vec4 cb = (bnorm) * b.getRadius() + b.getCenter(); return Sphere((ca + cb) / 2.0, (ca - cb).getLength() / 2.0); }
//* This only mostly works float Camera::getScreenRadius( const Sphere &sphere, float screenWidth, float screenHeight ) const { Vec2f screenCenter( worldToScreen( sphere.getCenter(), screenWidth, screenHeight ) ); Vec3f orthog = mViewDirection.getOrthogonal().normalized(); Vec2f screenPerimeter = worldToScreen( sphere.getCenter() + sphere.getRadius() * orthog, screenWidth, screenHeight ); return screenPerimeter.distance( screenCenter ); }
//----------------------------------------------------------------------- bool Frustum::isVisible(const Sphere& sphere, FrustumPlane* culledBy) const { // Make any pending updates to the calculated frustum planes updateFrustumPlanes(); // For each plane, see if sphere is on negative side // If so, object is not visible for (int plane = 0; plane < 6; ++plane) { // Skip far plane if infinite view frustum if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0) continue; // If the distance from sphere center to plane is negative, and 'more negative' // than the radius of the sphere, sphere is outside frustum if (mFrustumPlanes[plane].getDistance(sphere.getCenter()) < -sphere.getRadius()) { // ALL corners on negative side therefore out of view if (culledBy) *culledBy = (FrustumPlane)plane; return false; } } return true; }
//----------------------------------------------------------------------- bool Math::intersects(const Sphere& sphere, const AxisAlignedBox& box) { if (box.isNull()) return false; if (box.isInfinite()) return true; // Use splitting planes const Vector3& center = sphere.getCenter(); Real radius = sphere.getRadius(); const Vector3& min = box.getMinimum(); const Vector3& max = box.getMaximum(); // Arvo's algorithm Real s, d = 0; for (int i = 0; i < 3; ++i) { if (center.ptr()[i] < min.ptr()[i]) { s = center.ptr()[i] - min.ptr()[i]; d += s * s; } else if(center.ptr()[i] > max.ptr()[i]) { s = center.ptr()[i] - max.ptr()[i]; d += s * s; } } return d <= radius * radius; }
//* This only mostly works float Camera::getScreenRadius( const Sphere &sphere, float screenWidth, float screenHeight ) const { vec2 screenCenter( worldToScreen( sphere.getCenter(), screenWidth, screenHeight ) ); vec3 orthog = normalize( orthogonal( mViewDirection ) ); vec2 screenPerimeter = worldToScreen( sphere.getCenter() + sphere.getRadius() * orthog, screenWidth, screenHeight ); return distance( screenPerimeter, screenCenter ); }
//------------------------------------------------------------------------------ std::pair<bool, float> Math::intersects( const Ray& ray , const Sphere& sphere , bool discardInside ) { const Vector3& raydir = ray.getDirection(); const Vector3& rayorig = ray.getOrigin() - sphere.getCenter(); float radius = sphere.getRadius(); if (rayorig.squaredLength() <= radius*radius && discardInside) { return std::pair<bool, float>(true, 0.0f); } float a = raydir.dotProduct(raydir); float b = 2 * rayorig.dotProduct(raydir); float c = rayorig.dotProduct(rayorig) - radius*radius; float d = (b*b) - (4 * a * c); if (d < 0.0f) { return std::pair<bool, float>(false, 0.0f); } else { float t = ( -b - Math::Sqrt(d) ) / (2 * a); if (t < 0.0f) { t = ( -b + Math::Sqrt(d) ) / (2 * a); } return std::pair<bool, float>(true, t); } }
JNIEXPORT jdouble JNICALL Java_be_kuleuven_mech_rsg_jni_RsgJNI_getSphereRadius (JNIEnv *, jclass, jlong spherePtr) { Sphere* sphere = reinterpret_cast<Sphere*>(spherePtr); assert(sphere != 0); return sphere->getRadius(); }
void TerrainApp::drawTerrain() { mRd.getHeightsTexture().bind( 0 ); mRd.getNormalsTexture().bind( 1 ); mGradientTex.bind( 2 ); mSandNormalTex.bind( 3 ); mTerrainShader.bind(); mTerrainShader.uniform( "heightsTex", 0 ); mTerrainShader.uniform( "normalsTex", 1 ); mTerrainShader.uniform( "gradientTex", 2 ); mTerrainShader.uniform( "sandNormalTex", 3 ); mTerrainShader.uniform( "mvpMatrix", mSpringCam.mMvpMatrix ); mTerrainShader.uniform( "terrainScale", mTerrainScale ); mTerrainShader.uniform( "roomDims", mRoom.getDims() ); mTerrainShader.uniform( "zoomMulti", mZoomMulti );//lerp( mZoomMulti, 1.0f, mRoom.getPower() ) ); mTerrainShader.uniform( "power", mRoom.getPower() ); mTerrainShader.uniform( "eyePos", mSpringCam.getEye() ); mTerrainShader.uniform( "lightPos", mLightPos ); mTerrainShader.uniform( "fogColor", mFogColor ); mTerrainShader.uniform( "sandColor", mSandColor ); mTerrainShader.uniform( "mousePosNorm", -( mMousePosNorm - Vec2f( 0.5f, 0.5f ) ) * getElapsedSeconds() * 2.0f ); mTerrainShader.uniform( "spherePos", mSphere.getCenter() ); mTerrainShader.uniform( "sphereRadius", mSphere.getRadius() ); mTerrain.draw(); mTerrainShader.unbind(); }
void SphereForce::evalRepulsiveForce(Cell & c1, const Sphere & s) { float overlap=fmax(((c1.getCoord().distanceTo(s.getCentroid())+c1.getRadius())-s.getRadius()),0.0f); CVector cv; if(overlap==0.0f) { this->setValueXyz(cv); return; } std::cout<<c1.getID()<<"---"<<overlap<<std::endl; //cv=(c1.getCoord()/fmax(c1.getCoord().getAbsoluteMax(),1))*overlap; cv=c1.getCoord(); cv = cv/sqrt(pow(cv.getX(),2)+pow(cv.getY(),2)+pow(cv.getZ(),2)); //cv=cv*(overlap/(c1.getCoord().distanceTo(s.getCentroid())+c1.getRadius())); // utiliser fraction de la distance pour scaler cv.reverseSign(); c1.resetBoxCol(); /*if(strcmp(c1.getID().c_str(),"4")==1){ std::cout<<c1.getID().c_str()<<"overlap :"<<overlap<<"--"<<c1.getCoord().distanceTo(s.getCentroid())<<"\n fact : "<<(overlap/(c1.getCoord().distanceTo(s.getCentroid())+c1.getRadius()))<<"\nVecteur : "<<std::endl; cv.print(); c1.getCoord().print(); }*/ if(cv.getX()>0.0f) c1.setWl(true); if(cv.getX()<0.0f) c1.setWr(true); if(cv.getY()>0.0f) c1.setHl(true); if(cv.getY()<0.0f) c1.setHr(true); if(cv.getZ()>0.0f) c1.setDl(true); if(cv.getZ()<0.0f) c1.setDr(true); this->setValueXyz((cv*overlap*REPULSIVE_CONST)); }
void TerrainApp::drawSphere() { Vec3f spherePos = mSphere.getCenter(); Vec3f roomDims = mRoom.getDims(); float x = ( spherePos.x + roomDims.x ) / ( roomDims.x * 2.0f ); float y = ( spherePos.z + roomDims.z ) / ( roomDims.z * 2.0f );; Vec2f texCoord = Vec2f( x, y ); mCubeMap.bind(); mRd.getHeightsTexture().bind( 1 ); mRd.getNormalsTexture().bind( 2 ); mSphereShader.bind(); mSphereShader.uniform( "cubeMap", 0 ); mSphereShader.uniform( "heightsTex", 1 ); mSphereShader.uniform( "normalsTex", 2 ); mSphereShader.uniform( "mvpMatrix", mSpringCam.mMvpMatrix ); mSphereShader.uniform( "terrainScale", mTerrainScale ); mSphereShader.uniform( "eyePos", mSpringCam.getEye() ); mSphereShader.uniform( "fogColor", mFogColor ); mSphereShader.uniform( "sandColor", mSandColor ); mSphereShader.uniform( "power", mRoom.getPower() ); mSphereShader.uniform( "roomDims", mRoom.getDims() ); mSphereShader.uniform( "texCoord", texCoord ); mSphereShader.uniform( "sphereRadius", mSphere.getRadius() * 0.45f ); mSphereShader.uniform( "zoomMulti", mZoomMulti ); mSphereShader.uniform( "timePer", mRoom.getTimePer() * 1.5f + 0.5f ); gl::draw( mSphere, 128 ); mSphereShader.unbind(); }
void Scene::addSphere(geovalue *pos, geovalue rad, Material *mat) { Vector3D p1(pos[0],pos[1],pos[2]); for (int i=0; i<objects.size(); ++i) { Sphere * s; if ((s = dynamic_cast<Sphere*>(objects[i]))) { Vector3D distvec = s->getPosition() - p1; float dist = distvec.length(); float minDist = rad + s->getRadius(); if (dist < minDist) { rad = (minDist - s->getRadius())/2.0; pos[1] = -1.0 + rad; } } } objects.push_back(new Sphere(pos, mat, rad, this)); }
void ArcballTestApp::keyDown( KeyEvent event ) { if( event.getChar() == 'f' ) { mCam.setPerspective( randFloat( 5, 140 ), getWindowAspectRatio(), 1.0f, 10.0f ); } else if( event.getChar() == 'd' ) { mUsingCameraUi = ! mUsingCameraUi; if( mUsingCameraUi ) mDebugCam = mCam; } else if ( event.getChar() == 'c' ) { if( mArcball.isUsingConstraint() ) mArcball.setNoConstraintAxis(); else mArcball.setConstraintAxis( normalize( vec3( randFloat(), randFloat(), randFloat() ) ) ); } else if( event.getChar() == 'z' ) { mZLookAt /= 10; mCam.lookAt( vec3( 0, 0, 5 ), vec3( mZLookAt ) ); } else if( event.getChar() == 'r' ) { mEarthSphere.setCenter( vec3( randFloat(2), randFloat(1), randFloat( -4, 0 ) ) ); mEarth = gl::Batch::create( geom::Sphere( Sphere( vec3(0), mEarthSphere.getRadius() ) ).subdivisions( 50 ), gl::getStockShader( gl::ShaderDef().texture() ) ); mArcball.setSphere( mEarthSphere ); } }
//----------------------------------------------------------------------- bool Frustum::isVisible(const Sphere& sphere, FrustumPlane* culledBy) const { updateFrustumPlanes(); // 遍历视锥体的每个平面,对每个平面, 见如果所有的点都在反面 // 如果这样,对象不可见 for (int plane = 0; plane < 6; ++plane) { // 如果视锥体空间无限,跳过 if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0) continue; // 如果球体中心到平面的距离为负,并且大于球体半径,那么球在视锥体之外 if (mFrustumPlanes[plane].getDistance(sphere.getCenter()) < -sphere.getRadius()) { // 所有的角在反面,那么不在视野 if (culledBy) *culledBy = (FrustumPlane)plane; return false; } } return true; }
/** Checks how the box intersects with the sphere. */ Intersection intersect( const Sphere &one, const AxisAlignedBox &two ) { OctreeSceneManager::intersect_call++; // Null box? if (two.isNull()) return OUTSIDE; if (two.isInfinite()) return INTERSECT; float sradius = one.getRadius(); sradius *= sradius; Vector3 scenter = one.getCenter(); const Vector3& twoMin = two.getMinimum(); const Vector3& twoMax = two.getMaximum(); float s, d = 0; Vector3 mndistance = ( twoMin - scenter ); Vector3 mxdistance = ( twoMax - scenter ); if ( mndistance.squaredLength() < sradius && mxdistance.squaredLength() < sradius ) { return INSIDE; } //find the square of the distance //from the sphere to the box for ( int i = 0 ; i < 3 ; i++ ) { if ( scenter[ i ] < twoMin[ i ] ) { s = scenter[ i ] - twoMin[ i ]; d += s * s; } else if ( scenter[ i ] > twoMax[ i ] ) { s = scenter[ i ] - twoMax[ i ]; d += s * s; } } bool partial = ( d <= sradius ); if ( !partial ) { return OUTSIDE; } else { return INTERSECT; } }
void BoundingBox::set(const Sphere& sphere) { Vector3 center = sphere.getCenter(); float radius = sphere.getRadius(); min = center + Vector3(-radius, -radius, -radius); max = center + Vector3(radius, radius, radius); }
float DistancePointSphere ( Vector const & V, Sphere const & S ) { float dist = DistancePointPoint(V,S.getCenter()) - S.getRadius(); if(dist < 0.0f) dist = 0.0f; return dist; }
Range ProjectAxis ( Line3d const & L, Sphere const & S ) { real d = S.getRadius() / L.getNormal().magnitude(); real c = ProjectAxis( L, S.getCenter() ); return Range( c - d, c + d ); }
real DistanceSphereCylinder ( Sphere const & S, Cylinder const & C ) { float dist = DistancePointCylinder(S.getCenter(),C); dist -= S.getRadius(); return dist; }
bool Math::intersected(const Sphere& sphere01, const Sphere& sphere02) { Vector3 cen01 = sphere01.getCenter(); Vector3 cen02 = sphere02.getCenter(); Real d = Sqrt(cen01 * cen02); if(d < sphere01.getRadius() + sphere02.getRadius()) { return true; } else { return false; } }
bool Sphere::isOtherInside(const Sphere& other) const { vec3 axis(other.m_Position - m_Position); if (lengthSqr(axis) < sqr(m_Radius - other.getRadius())) return true; return false; }
ContainmentResult TestSphereOCylinder ( Sphere const & A, OrientedCylinder const & B ) { Vector localCenter = B.transformToLocal(A.getCenter()); Sphere localSphere(localCenter,A.getRadius()); return Test( localSphere, B.getLocalShape() ); }
void Collide::pointSphereCollide(const Body * point_, const Body * sphere_) { Point *point = (Point*)point_; Sphere *sphere = (Sphere*)sphere_; float distance = 0.0f; distance = (point->getPoint() - sphere->getCenter()).Length(); setCollide(distance < sphere->getRadius()); setDistance(distance - sphere->getRadius()); // compute the response vectors Vector3 responseObject1 = point_->getCenter() - sphere_->getCenter(); Vector3 responseObject2 = sphere_->getCenter() - point_->getCenter(); setResponseObject1(responseObject1); setResponseObject2(responseObject2); }
void ArcballTestApp::draw() { CameraPersp &cam = ( mUsingCameraUi ) ? mDebugCam : mCam; gl::clear( Color( 0, 0.0f, 0.15f ) ); gl::setMatrices( cam ); // draw the earth gl::enableDepthRead(); gl::enableDepthWrite(); gl::translate( mEarthSphere.getCenter() ); gl::rotate( mArcball.getQuat() ); mEarthTex->bind(); mEarth->draw(); // draw constraint axis if( mArcball.isUsingConstraint() ) { gl::setMatrices( cam ); gl::color( 1, 1, 0 ); gl::translate( mEarthSphere.getCenter() ); gl::rotate( glm::rotation( vec3( 0, 1, 0 ), mArcball.getConstraintAxis() ) ); mConstraintAxis->draw(); } gl::disableDepthRead(); // draw from vector marker gl::setMatrices( cam ); gl::color( 0, 1, 0.25f ); gl::translate( mEarthSphere.getCenter() + mArcball.getFromVector() * mEarthSphere.getRadius() ); mMarker->draw(); // draw to vector marker gl::setMatrices( cam ); gl::color( 1, 0.5f, 0.25f ); gl::translate( mEarthSphere.getCenter() + mArcball.getToVector() * mEarthSphere.getRadius() ); mMarker->draw(); // draw the elliptical axes gl::setMatricesWindow( getWindowSize() ); gl::color( 1, 0, 0 ); vec2 center, axisA, axisB; mCam.calcScreenProjection( mEarthSphere, getWindowSize(), ¢er, &axisA, &axisB ); gl::drawLine( center - axisA, center + axisA ); gl::drawLine( center - axisB, center + axisB ); }
AxialBox EncloseABox ( Sphere const & sphere ) { float r = sphere.getRadius(); Vector c = sphere.getCenter(); Vector d(r,r,r); return AxialBox( c + d, c - d ); }