Esempio n. 1
0
int draw(Scene& myScene)
{

    unsigned char* img;
    img = (unsigned char*)tga_create(myScene.width, myScene.height, TGA_TRUECOLOR_24);
    int img_index = 0;
    
    for(int m = 0; m<myScene.height*myScene.width*3; m++)
      img[m]=0;
    
  
    for(int y = 0; y < myScene.height; y++)
      for(int x = 0; x < myScene.width; x++)
      {		Ray viewRay;
		viewRay.o.x = x;
		viewRay.o.y = y;
		viewRay.o.z = -1000.0;
		viewRay.d.x = 0.0;
		viewRay.d.y = 0.0;
		viewRay.d.z = 1.0;
		viewRay.reflected = 0;
		float red = 0, green = 0, blue = 0; 
		float coef = 1.0;
		int level = 0;
		int repeatFlag = 0;
		int lastfrontSphere = -1;
		int frontSphere = -1;
		int lastfrontTriangle = -1;
		int frontTriangle = -1;
		
		do{
			Point inter;
			Point frontInter;
			float t_inter;
			Matrix iMat;
			Ray newviewRay;
			int triangleisFront, sphereisFront;
			int flag;
			
			if(repeatFlag==0)
			{	
				int ret_val_trngl = 0;
				flag = 1;
				float t = 2000.0;
				frontSphere = -1;
				frontTriangle = -1;
				sphereisFront = 0;
				triangleisFront = 0;
				
				for(int i = 0; i<myScene.spheres.size(); i++)
				{	if(myScene.spheres[i].transformed==0)	
					{	if(raySphere(viewRay, myScene.spheres[i], t))
						{	frontSphere = i;
							t_inter = t;
						}
					}
					
					else if(myScene.spheres[i].transformed==1)
					{	if(lastfrontSphere!=i)	
						{	if(viewRay.reflected == 0)
							{	Matrix temp_iMat = invMat(myScene.spheres[i].mat);
								Ray temp_newviewRay;
								temp_newviewRay.o = transformPoint(temp_iMat, viewRay.o);
								temp_newviewRay.o = subPoint(temp_newviewRay.o, myScene.spheres[i].tlate);// we have to sub since it is a inverse transform
								temp_newviewRay.d = transformPoint(temp_iMat, viewRay.d);                 ///////////////*doubt*why???////

								if(raySphere(temp_newviewRay, myScene.spheres[i], t))
								{	    frontSphere = i;
									    iMat = temp_iMat;
									    t_inter = t;
									    newviewRay = temp_newviewRay;
									    newviewRay.reflected = 0;
								}
							}
							else
							{	Matrix temp_iMat = invMat(myScene.spheres[i].mat);
								if(raySphere(viewRay, myScene.spheres[i], t))
								{	frontSphere = i;
									iMat = temp_iMat;
									t_inter = t;
									newviewRay = viewRay;
									newviewRay.reflected = 0;
								}
							}  
						}
					}
				}
				
				viewRay.reflected = 0;
				
				for(int i = 0; i<myScene.triangles.size(); i++)
				{	ret_val_trngl = rayTriangle(viewRay, myScene.triangles[i], inter);
					if((ret_val_trngl==1)&&(lastfrontTriangle!=i))
					{	frontTriangle = i;
						frontInter = inter;
					}
				}
				
				if(frontSphere==-1)
					if(frontTriangle==-1)
					{	flag = 0;
						triangleisFront = 0;
						sphereisFront = 0;
						break;
					}	
					else 
					{	triangleisFront = 1;
						sphereisFront = 0;
					}
					
				if(frontSphere!=-1)
					if(frontTriangle==-1)
					{	triangleisFront = 0;
						sphereisFront = 1;
					}	
					else 
					{	triangleisFront = 1;
						sphereisFront = 1;
					}	
			}
			
			repeatFlag = 0;
			
			if((sphereisFront==1)&&(triangleisFront==0))
			{	
				if(myScene.spheres[frontSphere].transformed==0)
				{	Point tempo = multPoint(t_inter, viewRay.d);
					Point newStart = addPoint(viewRay.o, tempo);
					Point n = subPoint(newStart, myScene.spheres[frontSphere].c);
					float temp = multPoint(n, n);
					if (temp == 0.0f) 
						break;
					temp = 1.0f / sqrtf(temp); 
					n = multPoint(temp, n);			//normal
				
					Material currentMat = myScene.materials[myScene.spheres[frontSphere].materialId];
					
					for (int j = 0; j < myScene.lights.size(); j++) 
					{
						Light light = myScene.lights[j];
						Point dist = subPoint(light.pos, newStart);
						
						if (multPoint(n, dist) <= 0.0f)
						  continue;
						
						float t = sqrtf(multPoint(dist, dist));

						if ( t <= 0.0f )
						  continue;
						  
						Ray lightRay;
						lightRay.o = newStart;
						lightRay.d = multPoint((1/t), dist);
						
						bool inShadow = false; 
						
						for (int k = 0; k < myScene.spheres.size(); k++) 
						{
						    if (raySphere(lightRay, myScene.spheres[k], t)) 
						    {	inShadow = true;
							break;
						    }
						}
						
						if (!inShadow) 
						{    // lambert
						    float lambert = multPoint(n, lightRay.d) * coef;
						    red += lambert * light.col.r * currentMat.r;
						    green += lambert * light.col.g * currentMat.g;
						    blue += lambert * light.col.b * currentMat.b;
						}
						
					}
					
					coef *= currentMat.reflection;
					float reflet = 2.0f * multPoint(viewRay.d, n);
					viewRay.o = newStart;
					Point temp_2 = multPoint(reflet, n);
					viewRay.d = subPoint(viewRay.d, temp_2);
					viewRay.reflected = 0;
					level++;
				}
				
				else if (myScene.spheres[frontSphere].transformed==1)
				{	
					Point tempo = multPoint(t_inter, newviewRay.d);
					Point newStart = addPoint(newviewRay.o, tempo);			//intersection point in sphere space
					Point newStart_2 = transformPoint(myScene.spheres[frontSphere].mat, newStart);//intersection point in ellipsoid space
					newStart_2 = addPoint(newStart_2, myScene.spheres[frontSphere].tlate); 
					
					Point n = subPoint(newStart, myScene.spheres[frontSphere].c);
					float temp = multPoint(n, n);
					if (temp == 0.0f) 
						break;
					temp = 1.0f / sqrtf(temp); 
					n = multPoint(temp, n);
					
					//convert normal to new worldspace
					Matrix iMat_2 = transMat(iMat);
					Point n_orig = n;
					n = transformPoint(iMat_2, n);
					
					Material currentMat = myScene.materials[myScene.spheres[frontSphere].materialId];

					for (int j = 0; j < myScene.lights.size(); j++) 
					{
						Light light = myScene.lights[j];
						Point dist = subPoint(light.pos, newStart_2);
						
						if (multPoint(n, dist) <= 0.0f)
						  continue;
						
						float t2 = sqrtf(multPoint(dist, dist));
						if ( t2 <= 0.0f )
						  continue;
						  
						Ray lightRay;
						lightRay.o = newStart_2;
						lightRay.d = multPoint((1/t2), dist);
						lightRay.reflected = 0;
						
						Point dist_temp = subPoint(light.pos, newStart);
						float t_temp = sqrtf(multPoint(dist_temp, dist_temp));
						
						bool inShadow = false; 
						Ray newlightRay;
						
						for (int k = 0; k < myScene.spheres.size(); k++) 
						{
						    newlightRay.o = newStart;
						    newlightRay.d = transformPoint(iMat, lightRay.d);
						    newlightRay.reflected = 0;
						    
						    if((k!=frontSphere) && (k!=lastfrontSphere))
							if (raySphere(newlightRay, myScene.spheres[k], t_temp)) 
							{	inShadow = true;
								break;
							}
						}
						
						if (!inShadow) 
						{    // lambert
						    float lambert = multPoint(n, lightRay.d) * coef;
						    red += lambert * light.col.r * currentMat.r;
						    green += lambert * light.col.g * currentMat.g;
						    blue += lambert * light.col.b * currentMat.b;
						}
						
						
					}
					lastfrontSphere = frontSphere;
					coef *= currentMat.reflection;
					float reflet = 2.0f * multPoint(newviewRay.d, n_orig);
					viewRay.o = newStart_2;
					Point temp_2 = multPoint(reflet, n_orig);
					viewRay.d = subPoint(newviewRay.d, temp_2);
					viewRay.reflected = 1;
					level++;
				}
			}

			else if((sphereisFront==0)&&(triangleisFront==1))
			{
				Point u_n = subPoint(myScene.triangles[frontTriangle].v1, frontInter);
				Point v_n = subPoint(myScene.triangles[frontTriangle].v2, frontInter);
				Point n = crossProduct(v_n, u_n);		//pay attention here
				
				float temp = multPoint(n, n);
				if (temp == 0.0f) 
					flag = 0;

				temp = 1.0f / sqrtf(temp); 
				n = multPoint(temp, n);			//normal
				
				Material currentMat = myScene.materials[myScene.triangles[frontTriangle].materialId];
				
				for (int j = 0; j < myScene.lights.size(); j++) 
				{
					Light light = myScene.lights[j];
					Point dist = subPoint(light.pos, frontInter);
					
					if (multPoint(n, dist) <= 0.0f)
					  continue;
					
					float t = sqrtf(multPoint(dist, dist));

					if ( t <= 0.0f )
					  continue;
					  
					Ray lightRay;
					lightRay.o = frontInter;
					lightRay.d = multPoint((1/t), dist);
					
					Point temp_inter;
					
					for (int k = 0; k < myScene.triangles.size(); k++) 
					{
					    if((k!=frontTriangle) && (k!=lastfrontTriangle))
						if ((rayTriangle(lightRay, myScene.triangles[k], temp_inter)==1)) 
						{   flag = 0;
						    break;
						}
					}
					
					if(flag == 1)
					{	float lambert = multPoint(n, lightRay.d) * coef;
						red += lambert * light.col.r * currentMat.r;
						green += lambert * light.col.g * currentMat.g;
						blue += lambert * light.col.b * currentMat.b;
					}
					
					lastfrontTriangle = frontTriangle;	//important
					
				}
				
				coef *= currentMat.reflection;
				float reflet = 2.0f * multPoint(viewRay.d, n);
				viewRay.o = frontInter;
				Point temp_2 = multPoint(reflet, n);
				viewRay.d = subPoint(viewRay.d, temp_2);
				viewRay.reflected = 1;
				level++;
			}
			
			else if((sphereisFront==1)&&(triangleisFront==1))
			{
				Point tempo = multPoint(t_inter, viewRay.d);
				Point newStart = addPoint(viewRay.o, tempo);
				
				if(newStart.z <= frontInter.z)
					triangleisFront=0;
				else
					sphereisFront = 0;
			  
				repeatFlag = 1;
			}
			  
			
		}while((coef>0.0f)&&(level<10));
		
		img[img_index] = (unsigned char)(min(red*255.0f, 255.0f));
		img[img_index+1] = (unsigned char)(min(green*255.0f, 255.0f));
		img[img_index+2] = (unsigned char)(min(blue*255.0f, 255.0f));
		img_index = img_index+3;
      }
 
  int ret_value = tga_write_rle( "output3.tga", myScene.width, myScene.height, img, TGA_TRUECOLOR_24); 
  return 1;
}
bool    btContinuousConvexCollision::calcTimeOfImpact(
                const btTransform& fromA,
                const btTransform& toA,
                const btTransform& fromB,
                const btTransform& toB,
                CastResult& result)
{

    m_simplexSolver->reset();

    /// compute linear and angular velocity for this interval, to interpolate
    btVector3 linVelA,angVelA,linVelB,angVelB;
    btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA);
    btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB);


    btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
    btScalar boundingRadiusB = m_convexB->getAngularMotionDisc();

    btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
    btVector3 relLinVel = (linVelB-linVelA);

    btScalar relLinVelocLength = (linVelB-linVelA).length();

    if ((relLinVelocLength+maxAngularProjectedVelocity) == 0.f)
        return false;


    btScalar radius = btScalar(0.001);

    btScalar lambda = btScalar(0.);
    btVector3 v(1,0,0);

    int maxIter = MAX_ITERATIONS;

    btVector3 n;
    n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
    bool hasResult = false;
    btVector3 c;

    btScalar lastLambda = lambda;
    //btScalar epsilon = btScalar(0.001);

    int numIter = 0;
    //first solution, using GJK


    btTransform identityTrans;
    identityTrans.setIdentity();

    btSphereShape    raySphere(btScalar(0.0));
    raySphere.setMargin(btScalar(0.));


//    result.drawCoordSystem(sphereTr);

    btPointCollector    pointCollector1;

    {

        btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
        btGjkPairDetector::ClosestPointInput input;

        //we don't use margins during CCD
    //    gjk.setIgnoreMargin(true);

        input.m_transformA = fromA;
        input.m_transformB = fromB;
        gjk.getClosestPoints(input,pointCollector1,0);

        hasResult = pointCollector1.m_hasResult;
        c = pointCollector1.m_pointInWorld;
    }

    if (hasResult)
    {
        btScalar dist;
        dist = pointCollector1.m_distance;
        n = pointCollector1.m_normalOnBInWorld;

        btScalar projectedLinearVelocity = relLinVel.dot(n);

        //not close enough
        while (dist > radius)
        {
            numIter++;
            if (numIter > maxIter)
            {
                return false; //todo: report a failure
            }
            btScalar dLambda = btScalar(0.);

            projectedLinearVelocity = relLinVel.dot(n);

            //calculate safe moving fraction from distance / (linear+rotational velocity)

            //btScalar clippedDist  = GEN_min(angularConservativeRadius,dist);
            //btScalar clippedDist  = dist;

            //don't report time of impact for motion away from the contact normal (or causes minor penetration)
            if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
                return false;

            dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);



            lambda = lambda + dLambda;

            if (lambda > btScalar(1.))
                return false;

            if (lambda < btScalar(0.))
                return false;


            //todo: next check with relative epsilon
            if (lambda <= lastLambda)
            {
                return false;
                //n.setValue(0,0,0);
                break;
            }
            lastLambda = lambda;



            //interpolate to next lambda
            btTransform interpolatedTransA,interpolatedTransB,relativeTrans;

            btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA);
            btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
            relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);

            result.DebugDraw( lambda );

            btPointCollector    pointCollector;
            btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
            btGjkPairDetector::ClosestPointInput input;
            input.m_transformA = interpolatedTransA;
            input.m_transformB = interpolatedTransB;
            gjk.getClosestPoints(input,pointCollector,0);
            if (pointCollector.m_hasResult)
            {
                if (pointCollector.m_distance < btScalar(0.))
                {
                    //degenerate ?!
                    result.m_fraction = lastLambda;
                    n = pointCollector.m_normalOnBInWorld;
                    result.m_normal=n;//.setValue(1,1,1);// = n;
                    result.m_hitPoint = pointCollector.m_pointInWorld;
                    return true;
                }
                c = pointCollector.m_pointInWorld;
                n = pointCollector.m_normalOnBInWorld;
                dist = pointCollector.m_distance;
            } else
            {
                //??
                return false;
            }

        }

        if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=result.m_allowedPenetration)//SIMD_EPSILON)
            return false;

        result.m_fraction = lambda;
        result.m_normal = n;
        result.m_hitPoint = c;
        return true;
    }

    return false;

/*
//todo:
    //if movement away from normal, discard result
    btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
    if (result.m_fraction < btScalar(1.))
    {
        if (move.dot(result.m_normal) <= btScalar(0.))
        {
        }
    }
*/

}
Esempio n. 3
0
int main() {
  float r[3], s[3];
  float radius;
  return raySphere(r, s, radius);
}