Example #1
0
void BeginRender()
{

    cout<<"\nBeginning Render...";
    
    float alpha = camera.fov;
    float l = 1.0;
    float h = l * tan(alpha/2.0 *(M_PI/180));
    float aspectRatio = (float)camera.imgWidth/camera.imgHeight;
    float s = aspectRatio * h;
    float dx = (2 * s)/camera.imgWidth;
    float dy = -(2 * h)/camera.imgHeight;
    float dxx = dx/2,dyy=dy/2;
    Point3 K(-s,h,-l);
    K.x += dxx;
    K.y += dyy;
    for(int i = 0; i< camera.imgHeight; i++){
        
        for(int j = 0; j<camera.imgWidth; j++){
            
            K.x += dx;
            Matrix3 RotMat;
            
            Point3 dvec = camera.dir - camera.pos;
            Point3 svec = camera.up.Cross(dvec);
            dvec.Normalize();
            svec.Normalize();
            camera.up.Normalize();
            RotMat.Set(svec,camera.up, dvec);
            Ray r(camera.pos, K);
            
            r.dir=r.dir*RotMat;
            
            r.dir.Normalize();
            
            HitInfo hInfo;
            hInfo.Init();
            if(rootNode.GetNumChild()>0){
//                for(int k=0; k < rootNode.GetNumChild(); ++k){
//                    RayTrace(rootNode.GetChild(k),r,i * camera.imgWidth + j);
//                }
                if(RayTrace_2(r, hInfo))
                {
                    renderImage.PutPixel(i *camera.imgWidth+j, white, hInfo.z);
                }
                else renderImage.PutPixel(i *camera.imgWidth+j, black, BIGFLOAT);
            }
            
            
        }
        K.x = -s;
        K.x += dxx;
        K.y += dy;
    }
    cout<<"Render Complete"<<endl;
    renderImage.ComputeZBufferImage();
    renderImage.SaveZImage("/Users/varunk/Desktop/RayTracerProj1/RayTracerProj1/zbuffer.ppm");
    renderImage.SaveImage("/Users/varunk/Desktop/RayTracerProj1/RayTracerProj1/renderimage.ppm");
    
}
Example #2
0
void getOrthoNormalBasisVector(Point3 i_up, Point3 &o_out_vector /*U*/, Point3& o_vector_right /*v*/)
{
    Point3 randomVectorW;
    //bool foundRandomVector = false;
    while (true)
    {
        randomVectorW = getRandomVector();
        if ( fabs(i_up.Dot(randomVectorW)) < RANDOMCOSINEANGLE)
        {
            o_out_vector = i_up.Cross(randomVectorW);
            o_vector_right = i_up.Cross(o_out_vector).GetNormalized();
            o_out_vector.Normalize();
            break;
        }
    }
}
Example #3
0
void ResetVert (PatchMesh *patch)
{
	// Make a edge table
	// Static table to avoid alloc prb
	CVertexNeighborhood& edgeTab=vertexNeighborhoodGlobal;
	edgeTab.build (*patch);

	// For each vertices
	for (int nV=0; nV<patch->numVerts; nV++)
	{
		// Selected ?
		if (patch->vertSel[nV])
		{
			Point3 vert=patch->verts[nV].p;
			Point3 normal (0,0,0);

			// Count of neigbor for vertex n
			uint listSize=edgeTab.getNeighborCount (nV);

			// List of neigbor
			const uint* pList=edgeTab.getNeighborList (nV);

			// For each neigbor
			uint nn;
			for (nn=0; nn<listSize; nn++)
			{
#if (MAX_RELEASE < 4000)
				// Compute average plane
				if (patch->edges[pList[nn]].patch1!=-1)
					normal+=patch->PatchNormal(patch->edges[pList[nn]].patch1);
				if (patch->edges[pList[nn]].patch2!=-1)
					normal+=patch->PatchNormal(patch->edges[pList[nn]].patch2);
#else // (MAX_RELEASE <= 4000)
				// Compute average plane
				if (patch->edges[pList[nn]].patches[0]!=-1)
					normal+=patch->PatchNormal(patch->edges[pList[nn]].patches[0]);
				if (patch->edges[pList[nn]].patches[1]!=-1)
					normal+=patch->PatchNormal(patch->edges[pList[nn]].patches[1]);
#endif // (MAX_RELEASE <= 4000)
			}
			
			// Normalize
			normal=normal.Normalize();
			
			// Plane
			float fD=-DotProd(normal, vert);

			// Reset normales
			float fNorme=0.f;

			// For each neigbor
			for (nn=0; nn<listSize; nn++)
			{
				Point3 vect2=patch->verts[(patch->edges[pList[nn]].v1==nV)?patch->edges[pList[nn]].v2:patch->edges[pList[nn]].v1].p;
				vect2-=vert;
				vect2/=3.f;
				Point3 tmp1=CrossProd (vect2, normal);
				tmp1=CrossProd (normal, tmp1);
				tmp1=Normalize(tmp1);
				int nTang=(patch->edges[pList[nn]].v1==nV)?patch->edges[pList[nn]].vec12:patch->edges[pList[nn]].vec21;
				patch->vecs[nTang].p=vert+tmp1*DotProd (tmp1,vect2);
				tmp1=patch->vecs[nTang].p;
				tmp1-=vert;
				fNorme+=tmp1.Length();
			}

			// Renorme new normal
			/*fNorme/=(float)edgeTab[nV].size();
			ite=edgeTab[nV].begin();
			while (ite!=edgeTab[nV].end())
			{
				int nTang=(patch->edges[pList[nn]].v1==nV)?patch->edges[pList[nn]].vec12:patch->edges[pList[nn]].vec21;
				patch->vecs[nTang].p=fNorme*(Normalize(patch->vecs[nTang].p-vert))+vert;

				ite++;
			}*/
		}
	}
	patch->computeInteriors();
	patch->InvalidateGeomCache ();
}
Example #4
0
Color MtlBlinn::Shade(const Cone &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{
    float bias = BIAS_SHADING;
    Color shade;
    Color rShade = Color(0,0,0);
    Color tShade = Color(0,0,0);
    const Material *mat;
    mat = hInfo.node->GetMaterial();
    const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat);
//    cout<<"HInfo front: "<<hInfo.front<<endl;
    /* local copy */
    Point3 P;
    P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z);
    Cone iRay = ray;
    
    Color ambInt = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw);
    Color allOther = Color(0,0,0);
    Color diffuse = mb->diffuse.Sample(hInfo.uvw, hInfo.duvw);
    Color ambComponent = Color(0,0,0);
    Point3 newN = hInfo.N;
    
    
    for ( unsigned int i=0; i<lights.size(); i++ ) {
        if(lights[i]->IsAmbient()){
//            cout<<"ambient "<<endl;
            Color intensity = lights[i]->Illuminate(hInfo.p);
            ambComponent += (ambInt * intensity);
            continue;
        }
        else{
//            cout<<"other lighting  "<<endl;
            Point3 L = -lights[i]->Direction(P);
            L.Normalize();
            
            Point3 V = ray.p - P;
            V.Normalize();
            
            Point3 LplusV = L + V;
            Point3 H = (L+V)/LplusV.Length();
            H.Normalize();
            
            float alpha = mb->glossiness;
//            Point3 N = hInfo.N;
            Point3 N = newN;
            float S = H.Dot(N);
            S = pow(S,alpha);
            float costheta = L.Dot(N)/(L.Length() * N.Length());
            Color intensity = lights[i]->Illuminate(P);
//            cout<<"costheta "<<endl;
            allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular.Sample(hInfo.uvw, hInfo.duvw))) ;
        }
        /* finally add inta*cola + intall*costheta*(cold + s* colS)*/
        shade = ambComponent  + allOther;
    }
    
    /* Calculate refraction */
    if(refraction.GetColor().r>0 && bounceCount>0){
        //compute new jittered normal
        float gloss = refractionGlossiness;
        if(gloss){
            float random = rand()/(float)RAND_MAX;
            float rRadius = sqrtf(random) * gloss;
            random = rand()/(float)RAND_MAX;
            float rAngle =  random * 2.0 * M_PI;
            float x = rRadius * cos(rAngle);
            float y = rRadius * sin(rAngle);
            Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir;
            normalDir = hInfo.N;
            //    normalDir.Normalize();
            if(normalDir.Dot(xAxis) > 0.7)  v1 = normalDir.Cross(yAxis);
            else v1 = normalDir.Cross(xAxis);
            v2 = v1.Cross(normalDir);
            v1.Normalize(); v2.Normalize();
            v1 *= x;
            v2 *= y;
            
            newN = hInfo.N + v1.Length() + v2.Length();
            newN.Normalize();
        }
        else{
            newN = hInfo.N;
        }
        //-------------------------------------
        
        Color reflShade = Color(0,0,0);
        float R0, Refl = 0.0f, Trans = 0.0f;
        HitInfo temp;
        temp.Init();
        
//        Point3 N = hInfo.N;
        Point3 N = newN;
//        Point3 V = Point3(iRay.p.x -  hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z);
        Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z);
        V.Normalize();
        float n1 = 1, n2 = 1;
        if(hInfo.front){ /* Hitting from outside */
//            temp.front = false;
            n2 = ior;
//            cout<<"outside "<<endl;
        }
        else if(!hInfo.front){ /* Transmission from the inside */
//            temp.front = true;
            n1 = ior;
//            cout<<"intside... "<<endl;
//            N = -hInfo.N;
            N *= -1;
        }
        float ratio_n = n1 / n2;
        
        float costheta_v = -V.Dot(N);        /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */

        float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v);
        Point3 T =   ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ;
//        cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl;
        Cone tRay = Cone(hInfo.p,T);
        
        //tRay.dir.Normalize();
        tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */
        tRay.p.y = tRay.p.y + bias *tRay.dir.y;
        tRay.p.z = tRay.p.z + bias *tRay.dir.z;
//        cout<<"B temp front: "<< temp.front<<endl;
        temp.timeInstance = hInfo.timeInstance;
        if(sin2theta_t <= 1){
            if(RayTrace_2(tRay, temp)){ /* ray tracing after refraction */
//                bounceCount--;
                tShade  =  temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount);
            }
            else{ /* no hit after refraction */
                tShade = environment.SampleEnvironment(tRay.dir);
                
            }
            /* Calculate Schlick's approximation */
            
            R0 = (n1 - n2)/(n1 + n2);
            R0 *= R0;
            double  X = 0.0;
            //                if(n1 > n2){
            //                    X = 1.0 - sqrtf(1.0 - sin2theta_t);
            //                }
            //                else{ X = 1.0 - costheta_v; }
            X = 1.0 - costheta_v;
            Refl = R0 + (1.0 - R0) *  X * X * X * X * X;
            Trans = 1.0 - Refl;
            
            tShade.r *= exp(-absorption.r * temp.z);
            tShade.g *= exp(-absorption.g * temp.z);
            tShade.b *= exp(-absorption.b * temp.z);
        }
        else {/* Total internal reflection */
            Refl = 1.0f;
        }
        
            
        
        
        /* Calculate reflection due to reflectance */
        if(bounceCount >0){
//            N = hInfo.N;
            N = newN;
            Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
            //V.Normalize();
            Point3 VR = 2 * V.Dot(N) * N - V;
            //VR.Normalize();
            Cone rRay = Cone(P + BIAS_SHADING * VR, VR);
            rRay.dir.Normalize();
            HitInfo temp1;
            temp1.Init();
            temp.timeInstance = hInfo.timeInstance;
            if(rootNode.GetNumChild()>0){
                if(RayTrace_2(rRay, temp1)){
                    bounceCount --;
                    reflShade = temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount);
                }
                else{
                    reflShade = environment.SampleEnvironment(rRay.dir);
//                    reflShade = Color(1,100,1);
                }
            }
        }
        
//        cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl;
        tShade = refraction.GetColor().r * (Trans * tShade + Refl * reflShade);
        
        
    }

    /* calculate reflection*/
    if(reflection.GetColor().r>0 && bounceCount > 0){
        //compute new jittered normal
        float gloss = reflectionGlossiness;
        if(gloss){
            float random = rand()/(float)RAND_MAX;
            float rRadius = sqrtf(random) * gloss;
            random = rand()/(float)RAND_MAX;
            float rAngle =  random * 2.0 * M_PI;
            float x = rRadius * cos(rAngle);
            float y = rRadius * sin(rAngle);
            Point3 xAxis(1,0,0), yAxis(0,1,0), v1, v2, normalDir;
            normalDir = hInfo.N;
            //    normalDir.Normalize();
            if(normalDir.Dot(xAxis) > 0.7)  v1 = normalDir.Cross(yAxis);
            else v1 = normalDir.Cross(xAxis);
            v2 = v1.Cross(normalDir);
            v1.Normalize(); v2.Normalize();
            v1 *= x;
            v2 *= y;
            
            newN = hInfo.N + v1+ v2;
            newN.Normalize();
        }
        else{
            newN = hInfo.N;
        }
        //-------------------------------------
        
        Point3 N = newN;//hInfo.N;
        Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
       // V.Normalize();
        Point3 VR = 2 * V.Dot(N) * N - V;
        Cone rRay = Cone(P + BIAS_SHADING * VR, VR);
        rRay.dir.Normalize();
        HitInfo temp;
        temp.Init();
        temp.timeInstance=hInfo.timeInstance;
        if(rootNode.GetNumChild()>0){
            if(RayTrace_2(rRay, temp)){
                bounceCount--;
                rShade = reflection.GetColor().r * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount);
            }
            else{
                rShade =  reflection.GetColor().r *environment.SampleEnvironment(rRay.dir);
//                rShade = Color(1,111,1);
            }
        }
    }
    
  
    
    /* Add shade with reflected and refracted colors */
    shade += (rShade + tShade);
    return shade;
};
Example #5
0
// Generate local to world from face info (pos, normal, etc)
Matrix3 plDistributor::IGenerateTransform(int iRepNode, int iFace, const Point3& pt, const Point3& bary) const
{
    const float kMinVecLengthSq = 1.e-6f;
    Matrix3 l2w(true);

    // First, set the scale
    Point3 scale;
    switch( fScaleLock )
    {
    case kLockX | kLockY:
        scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x);
        scale.y = scale.x;
        scale.z = fRand.RandRangeF(fScaleLo.z, fScaleHi.z);
        break;
    case kLockX | kLockY | kLockZ:
        scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x);
        scale.y = scale.z = scale.x;
        break;
    default:
        scale.x = fRand.RandRangeF(fScaleLo.x, fScaleHi.x);
        scale.y = fRand.RandRangeF(fScaleLo.y, fScaleHi.y);
        scale.z = fRand.RandRangeF(fScaleLo.z, fScaleHi.z);
        break;
    }

    l2w.Scale(scale);

    // Next up, get the rotation.
    // First we'll randomly rotate about local Z
    float azimRot = fRand.RandMinusOneToOne() * fAzimuthRange;
    Matrix3 azimMat;
    azimMat.SetRotateZ(azimRot);

    l2w = l2w * azimMat;

    // Now align with the surface.
    // Get the interpolated surface normal.
    Point3 surfNorm = IGetSurfaceNormal(iFace, bary);

    Matrix3 repNodeTM = fRepNodes[iRepNode]->GetNodeTM(TimeValue(0));

    Point3 alignVec = repNodeTM.GetRow(2);
    alignVec = alignVec * fWorldToSurfVec;
    alignVec = FNormalize(alignVec);

    Point3 norm = surfNorm + (alignVec - surfNorm) * fAlignWgt;
    // The norm can come out of this zero length, if the surace normal
    // is directly opposite the "natural" up direction and the weight
    // is 50% (for example). In that case, this is just a bad place
    // to drop this replicant.
    if( norm.LengthSquared() < kMinVecLengthSq )
    {
        l2w.IdentityMatrix();
        return l2w;
    }
    norm = norm.Normalize();

    // Randomize through the cone around that.
    Point3 rndNorm = norm;
    Point3 rndDir = IPerpAxis(norm);
    Point3 rndOut = rndDir ^ norm;
    rndDir *= fRand.RandMinusOneToOne();
    float len = sqrt(1.f - rndDir.LengthSquared());
    rndOut *= len;
    if( fRand.RandMinusOneToOne() < 0 )
        rndOut *= -1.f;
    Point3 rndPol = rndDir + rndOut;

    float polScale = fRand.RandZeroToOne() * fTanPolarRange;

    // Combine using the bunching factor
    polScale = polScale * (1.f - fPolarBunch) + polScale * polScale * fPolarBunch;

    rndPol *= polScale;
    rndNorm += rndPol;
    norm = rndNorm.Normalize();

    // Have "up" alignment, now just generate random dir vector perpindicular to up
    Point3 dir = repNodeTM.GetRow(1);
    dir = dir * fWorldToSurfVec;
    Point3 out = dir ^ norm;
    if( out.LengthSquared() < kMinVecLengthSq )
    {
        if( fAzimuthRange < M_PI * 0.5f )
        {
            l2w.IdentityMatrix();
            return l2w;
        }
        else
        {
            dir = IPerpAxis(norm);
            out = dir ^ norm;
        }
    }
    out = FNormalize(out);
    dir = norm ^ out;

    // If our "up" direction points into the surface, return an "up" direction
    // tangent to the surface. Also, make the "dir" direction point out from
    // the surface. So if the alignVec/fAlignWgt turns the replicant around
    // to penetrate the surface, it just lies down instead.
    //
    // There's an early out here, for the case where the surface normal is
    // exactly opposed to the destination normal. This usually means the
    // surface normal is directly opposite the alignVec. In that
    // case, we just want to bag it.
    if( DotProd(norm, surfNorm) < 0 )
    {
        dir = surfNorm;
        dir = dir.Normalize();
        out = dir ^ norm;
        if( out.LengthSquared() < kMinVecLengthSq )
        {
            l2w.IdentityMatrix();
            return l2w;
        }
        out = out.Normalize();
        norm = out ^ dir;
    }

    Matrix3 align;
    align.Set(out, dir, norm, Point3(0,0,0));

    l2w = l2w * align;


    // Lastly, set the position.
    Point3 pos = pt;
    const float offset = fRand.RandRangeF(fOffsetMin, fOffsetMax);
    pos += norm * offset;
    l2w.Translate(pos);

    l2w = l2w * fSurfNode->GetObjectTM(TimeValue(0));

    return l2w;
}
Example #6
0
Color MtlBlinn::Shade(const Ray &ray, const HitInfo &hInfo, const LightList &lights, int bounceCount) const{
    float bias = BIAS_SHADING;
    Color shade;
    Color rShade = Color(0,0,0);
    Color tShade = Color(0,0,0);
    const Material *mat;
    mat = hInfo.node->GetMaterial();
    const MtlBlinn* mb =static_cast<const MtlBlinn*>(mat);
//    cout<<"HInfo front: "<<hInfo.front<<endl;
    /* local copy */
    Point3 P;
    P.Set(hInfo.p.x,hInfo.p.y,hInfo.p.z);
    Ray iRay = ray;
    
    Color ambInt = mb->diffuse;
    Color allOther = Color(0,0,0);
    Color diffuse = mb->diffuse;;
    Color ambComponent = Color(0,0,0);
    
    for ( unsigned int i=0; i<lights.size(); i++ ) {
        if(lights[i]->IsAmbient()){
//            cout<<"ambient "<<endl;
            Color intensity = lights[i]->Illuminate(hInfo.p);
            ambComponent += (ambInt * intensity);
            continue;
        }
        else{
//            cout<<"other lighting  "<<endl;
            Point3 L = -lights[i]->Direction(P);
            L.Normalize();
            
            Point3 V = ray.p - P;
            V.Normalize();
            
            Point3 LplusV = L + V;
            Point3 H = (L+V)/LplusV.Length();
            H.Normalize();
            
            float alpha = mb->glossiness;
            Point3 N = hInfo.N;
            float S = H.Dot(N);
            S = pow(S,alpha);
            float costheta = L.Dot(N)/(L.Length() * N.Length());
            Color intensity = lights[i]->Illuminate(P);
//            cout<<"costheta "<<endl;
            allOther += intensity * (costheta>0?costheta:0) * (diffuse + S * (mb->specular)) ;
        }
        /* finally add inta*cola + intall*costheta*(cold + s* colS)*/
        shade = ambComponent  + allOther;
    }
    
    /* Calculate refraction */
    if(refraction.Grey()>0 && bounceCount>0){
        Color reflShade = Color(0,0,0);
        float R0, Refl = 0.0f, Trans = 0.0f;
        HitInfo temp;
        temp.Init();
        
        Point3 N = hInfo.N;
//        Point3 V = Point3(iRay.p.x -  hInfo.p.x, iRay.p.y - hInfo.p.y, iRay.p.z - hInfo.p.z);
        Point3 V = Point3(hInfo.p.x - iRay.p.x, hInfo.p.y - iRay.p.y, hInfo.p.z - iRay.p.z);
        V.Normalize();
        float n1 = 1, n2 = 1;
        if(hInfo.front){ /* Hitting from outside */
//            temp.front = false;
            n2 = ior;
//            cout<<"outside "<<endl;
        }
        else if(!hInfo.front){ /* Transmission from the inside */
//            temp.front = true;
            n1 = ior;
//            cout<<"intside... "<<endl;
            N = -hInfo.N;
        }
        float ratio_n = n1 / n2;
        
        float costheta_v = -V.Dot(N);        /* refer: http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf */

        float sin2theta_t = ratio_n * ratio_n * (1 - costheta_v * costheta_v);
        Point3 T =   ratio_n * V + (ratio_n * costheta_v - sqrtf(1 - sin2theta_t)) * N ;
//        cout<<ratio_n<<" "<<"cos_v "<<costheta_v<<" sin2theta_t "<<sin2theta_t<<endl;
        Ray tRay = Ray(hInfo.p,T);
        
        //tRay.dir.Normalize();
        tRay.p.x = tRay.p.x + bias *tRay.dir.x; /* add bias */
        tRay.p.y = tRay.p.y + bias *tRay.dir.y;
        tRay.p.z = tRay.p.z + bias *tRay.dir.z;
//        cout<<"B temp front: "<< temp.front<<endl;
        if(sin2theta_t <= 1){
            if(RayTrace_2(tRay, temp)){
//                bounceCount--;
//                cout<<"A temp front: "<< temp.front<<endl;
                tShade  =  temp.node->GetMaterial()->Shade(tRay,temp,lights,bounceCount);
                tShade.r *= exp(-absorption.r * temp.z);
                tShade.g *= exp(-absorption.g * temp.z);
                tShade.b *= exp(-absorption.b * temp.z);
//                shade = tShade; /* remove later */
//                return shade;
               
                
                /* Calculate Schlick's approximation */
                
                R0 = (n1 - n2)/(n1 + n2);
                R0 *= R0;
                double  X = 0.0;
//                if(n1 > n2){
//                    X = 1.0 - sqrtf(1.0 - sin2theta_t);
//                }
//                else{ X = 1.0 - costheta_v; }
                X = 1.0 - costheta_v;
                Refl = R0 + (1.0 - R0) *  X * X * X * X * X;
                Trans = 1.0 - Refl;
                
            }
        }
        else {/* Total internal reflection */
            Refl = 1.0f;
        }
        
        /* Calculate reflection due to reflectance */
        if(bounceCount >0){
            N = hInfo.N;
            Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
            //V.Normalize();
            Point3 VR = 2 * V.Dot(N) * N - V;
            //VR.Normalize();
            Ray rRay = Ray(P, VR);
            //rRay.dir.Normalize();
            rRay.p.x = rRay.p.x + bias *rRay.dir.x;
            rRay.p.y = rRay.p.y + bias *rRay.dir.y;
            rRay.p.z = rRay.p.z + bias *rRay.dir.z;
            HitInfo temp1;
            temp1.Init();
            if(rootNode.GetNumChild()>0){
                if(RayTrace_2(rRay, temp1)){
                    bounceCount --;
                    reflShade =   temp1.node->GetMaterial()->Shade(rRay, temp1, lights, bounceCount);
                }
            }
        }
        
//        cout<<"Refl: "<<Refl<<"Trans "<<Trans<<endl;
        tShade = refraction * (Trans * tShade + Refl * reflShade);
        
        
    }
    





    /* calculate reflection*/
    if(reflection.Grey()>0 && bounceCount > 0){

        Point3 N = hInfo.N;
        Point3 V = Point3(iRay.p.x -  P.x, iRay.p.y - P.y, iRay.p.z - P.z);
       // V.Normalize();
        Point3 VR = 2 * V.Dot(N) * N - V;
        Ray rRay = Ray(hInfo.p, VR);
        //rRay.dir.Normalize();
        rRay.p.x = rRay.p.x + bias *rRay.dir.x;
        rRay.p.y = rRay.p.y + bias *rRay.dir.y;
        rRay.p.z = rRay.p.z + bias *rRay.dir.z;
        HitInfo temp;
        temp.Init();
        if(rootNode.GetNumChild()>0){
            if(RayTrace_2(rRay, temp)){
                bounceCount--;
                rShade = reflection * temp.node->GetMaterial()->Shade(rRay, temp, lights, bounceCount);
            }
        }
    }
    
  
    
    /* Add shade with reflected and refracted colors */
    shade += (rShade + tShade);
    return shade;
};
Example #7
0
CVertexCandidate *CMaxMesh::GetVertexCandidate(CSkeletonCandidate *pSkeletonCandidate, int faceId, int faceVertexId)
{
    // check for valid mesh and physique modifier
    if((m_pIMesh == 0))
    {
        theExporter.SetLastError("Invalid handle.", __FILE__, __LINE__);
        return 0;
    }

    // check if face id is valid
    if((faceId < 0) || (faceId >= m_pIMesh->getNumFaces()))
    {
        theExporter.SetLastError("Invalid face id found.", __FILE__, __LINE__);
        return 0;
    }

    // check if face vertex id is valid
    if((faceVertexId < 0) || (faceVertexId >= 3))
    {
        theExporter.SetLastError("Invalid face vertex id found.", __FILE__, __LINE__);
        return 0;
    }

    // allocate a new vertex candidate
    CVertexCandidate *pVertexCandidate;
    pVertexCandidate = new CVertexCandidate();
    if(pVertexCandidate == 0)
    {
        theExporter.SetLastError("Memory allocation failed.", __FILE__, __LINE__);
        return 0;
    }

    // create the new vertex candidate
    if(!pVertexCandidate->Create())
    {
        delete pVertexCandidate;
        return 0;
    }

    // get vertex id
    int vertexId;
    vertexId = m_pIMesh->faces[faceId].v[faceVertexId];

    // get the absolute vertex position
    Point3 vertex;
    vertex = m_pIMesh->getVert(vertexId) * m_tm;

    // set the vertex candidate position
    pVertexCandidate->SetPosition(vertex.x, vertex.y, vertex.z);
    pVertexCandidate->SetUniqueId(vertexId);

    // get the absolute vertex normal
    Point3 normal;
    normal = GetVertexNormal(faceId, vertexId);
    normal = normal * Inverse(Transpose(m_tm));
    normal = normal.Normalize();

    // set the vertex candidate normal
    pVertexCandidate->SetNormal(normal.x, normal.y, normal.z);
 
  if(m_pIMesh->numCVerts > 0)
  { 
        VertColor vc;
        vc = m_pIMesh->vertCol[m_pIMesh->vcFace[faceId].t[faceVertexId]];
    CalVector vcCal(vc.x, vc.y, vc.z);
    pVertexCandidate->SetVertColor(vcCal);
  }  
 
    // get the vertex weight array
    float *pVertexWeights;
    pVertexWeights = m_pIMesh->getVertexWeights();
  //if( pVertexWeights == NULL ) {
    //    delete pVertexCandidate;
    //    theExporter.SetLastError("Mesh has no vertex weights", __FILE__, __LINE__);
    //    return 0;
  //}

    // get the vertex weight (if possible)
    float weight;
    if(pVertexWeights != 0)
    {
        weight = pVertexWeights[vertexId];
    }
    else
    {
        weight = 0.0f;
    }

    // another 3ds max weird behaviour:
    // zero out epsilon weights
    if(weight < 0.0005f) weight = 0.0f;

    // set the vertex candidate weight
    pVertexCandidate->SetPhysicalProperty(weight);

    // get the material id of the face
    int materialId;
    materialId = GetFaceMaterialId(faceId);

    if((materialId < 0) || (materialId >= (int)m_vectorStdMat.size()))
    {
        delete pVertexCandidate;
        theExporter.SetLastError("Invalid material id found.", __FILE__, __LINE__);
        return 0;
    }

    // get the material of the face
    StdMat *pStdMat;
    pStdMat = m_vectorStdMat[materialId];

    // loop through all the mapping channels and extract texture coordinates
    int mapId;
    for(mapId = 0; mapId < pStdMat->NumSubTexmaps(); mapId++)
    {
        // get texture map
        Texmap *pTexMap;
        pTexMap = pStdMat->GetSubTexmap(mapId);

        // check if map is valid
        if((pTexMap != 0) && (pStdMat->MapEnabled(mapId)))
        {
            // get the mapping channel
            int channel;
            channel = pTexMap->GetMapChannel();

            bool bValidUV;
            bValidUV = false;

            // extract the texture coordinate
            UVVert uvVert;
            if(m_pIMesh->mapSupport(channel))
            {
                TVFace *pTVFace;
                pTVFace = m_pIMesh->mapFaces(channel);

                UVVert *pUVVert;
                pUVVert = m_pIMesh->mapVerts(channel);

                uvVert = pUVVert[pTVFace[faceId].t[faceVertexId]];
                bValidUV = true;
            }
            else if(m_pIMesh->numTVerts > 0)
            {
                uvVert = m_pIMesh->tVerts[m_pIMesh->tvFace[faceId].t[faceVertexId]];
                bValidUV = true;
            }

            // if we found valid texture coordinates, add them to the vertex candidate
            if(bValidUV)
            {
                // apply a possible uv generator
                StdUVGen *pStdUVGen;
                pStdUVGen = (StdUVGen *)pTexMap->GetTheUVGen();
                if(pStdUVGen != 0)
                {
                    Matrix3 tmUV;
                    pStdUVGen->GetUVTransform(tmUV);
                    uvVert = uvVert * tmUV;
                }

                // add texture coordinate to the vertex candidate, inverting the y coordinate
                pVertexCandidate->AddTextureCoordinate(uvVert.x, 1.0f - uvVert.y);
            }
        }
    }

    // check for physique modifier
    if(m_modifierType == MODIFIER_PHYSIQUE)
    {
        // create a physique export interface
        IPhysiqueExport *pPhysiqueExport;
        pPhysiqueExport = (IPhysiqueExport *)m_pModifier->GetInterface(I_PHYINTERFACE);
        if(pPhysiqueExport == 0)
        {
            delete pVertexCandidate;
            theExporter.SetLastError("Physique modifier interface not found.", __FILE__, __LINE__);
            return 0;
        }

        // create a context export interface
        IPhyContextExport *pContextExport;
        pContextExport = (IPhyContextExport *)pPhysiqueExport->GetContextInterface(m_pINode);
        if(pContextExport == 0)
        {
            m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport);
            delete pVertexCandidate;
            theExporter.SetLastError("Context export interface not found.", __FILE__, __LINE__);
            return 0;
        }

        // set the flags in the context export interface
        pContextExport->ConvertToRigid(TRUE);
        pContextExport->AllowBlending(TRUE);

        // get the vertex export interface
        IPhyVertexExport *pVertexExport;
        pVertexExport = (IPhyVertexExport *)pContextExport->GetVertexInterface(vertexId);
        if(pVertexExport == 0)
        {
            pPhysiqueExport->ReleaseContextInterface(pContextExport);
            m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport);
            delete pVertexCandidate;
            theExporter.SetLastError("Vertex export interface not found.", __FILE__, __LINE__);
            return 0;
        }

        // get the vertex type
        int vertexType;
        vertexType = pVertexExport->GetVertexType();

        // handle the specific vertex type
        if(vertexType == RIGID_TYPE)
        {
            // typecast to rigid vertex
            IPhyRigidVertex *pTypeVertex;
            pTypeVertex = (IPhyRigidVertex *)pVertexExport;

                // add the influence to the vertex candidate
            // get the influencing bone
            if(!AddBoneInfluence(pSkeletonCandidate, pVertexCandidate, pTypeVertex->GetNode(), 1.0f))
            {
                pPhysiqueExport->ReleaseContextInterface(pContextExport);
                m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport);
                delete pVertexCandidate;
                theExporter.SetLastError("Invalid bone assignment.", __FILE__, __LINE__);
                return 0;
            }
        }
        else if(vertexType == RIGID_BLENDED_TYPE)
        {
            // typecast to blended vertex
            IPhyBlendedRigidVertex *pTypeVertex;
            pTypeVertex = (IPhyBlendedRigidVertex *)pVertexExport;

            // loop through all influencing bones
            int nodeId;
            for(nodeId = 0; nodeId < pTypeVertex->GetNumberNodes(); nodeId++)
            {
                // add the influence to the vertex candidate
                if(!AddBoneInfluence(pSkeletonCandidate, pVertexCandidate, pTypeVertex->GetNode(nodeId), pTypeVertex->GetWeight(nodeId)))
                {
                    pPhysiqueExport->ReleaseContextInterface(pContextExport);
                    m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport);
                    delete pVertexCandidate;
                    theExporter.SetLastError("Invalid bone assignment.", __FILE__, __LINE__);
                    return 0;
                }
            }
        }

        // release all interfaces
        pPhysiqueExport->ReleaseContextInterface(pContextExport);
        m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport);
    }
#if MAX_RELEASE >= 4000
    // check for skin modifier
    else if(m_modifierType == MODIFIER_SKIN)
    {
        // create a skin interface
        ISkin *pSkin;
        pSkin = (ISkin*)m_pModifier->GetInterface(I_SKIN);
        if(pSkin == 0)
        {
            delete pVertexCandidate;
            theExporter.SetLastError("Skin modifier interface not found.", __FILE__, __LINE__);
            return 0;
        }

        // create a skin context data interface
        ISkinContextData *pSkinContextData;
        pSkinContextData = (ISkinContextData *)pSkin->GetContextInterface(m_pINode);
        if(pSkinContextData == 0)
        {
            m_pModifier->ReleaseInterface(I_SKIN, pSkin);
            delete pVertexCandidate;
            theExporter.SetLastError("Skin context data interface not found.", __FILE__, __LINE__);
            return 0;
        }

        // loop through all influencing bones
        int nodeId;
        for(nodeId = 0; nodeId < pSkinContextData->GetNumAssignedBones(vertexId); nodeId++)
        {
            // get the bone id
            int boneId;
            boneId = pSkinContextData->GetAssignedBone(vertexId, nodeId);
            if(boneId < 0) continue;

            // add the influence to the vertex candidate
            if(!AddBoneInfluence(pSkeletonCandidate, pVertexCandidate, pSkin->GetBone(boneId), pSkinContextData->GetBoneWeight(vertexId, nodeId)))
            {
                m_pModifier->ReleaseInterface(I_SKIN, pSkin);
                delete pVertexCandidate;
                theExporter.SetLastError("Invalid bone assignment.", __FILE__, __LINE__);
                return 0;
            }
        }

        // release all interfaces
        m_pModifier->ReleaseInterface(I_SKIN, pSkin);
    }
#endif
        else if( m_modifierType == MODIFIER_MORPHER || m_modifierType == MODIFIER_NONE ) {
        }
        else 
    {
          theExporter.SetLastError("No physique/skin/morpher modifier found.", __FILE__, __LINE__);
          return 0;
    }

    return pVertexCandidate;
}
Example #8
0
Mesh*
TriObject::GetRenderMesh(TimeValue t, INode *inode, View &view, BOOL& needDelete)
{
	if (mDisableDisplacement || !(view.flags & RENDER_MESH_DISPLACEMENT_MAP)) {
		needDelete = FALSE;
		return &mesh;
	}
	// need to check the mesh and see if any face has a matId the requires displacment mapping
	BOOL needDisp = FALSE;

	// Get the material
	Mtl* pMtl = inode ? inode->GetMtl() : NULL;

	if (pMtl) {
		// does the mesh as a whole need it
		if (pMtl->Requirements(mesh.mtlIndex)&MTLREQ_DISPLACEMAP)
			needDisp = TRUE;

		if (!needDisp) {
			for (int f = 0; f < mesh.numFaces; f++) {
				if (pMtl->Requirements(mesh.getFaceMtlIndex(f))&MTLREQ_DISPLACEMAP) {
					needDisp = TRUE;
					break;
				}
			}
		}

		if (needDisp) {
            if (mesh.getNumFaces() == 0)
                return &mesh;

			Matrix3 otm;
			if (inode)
				otm = inode->GetObjectTM(t);
			else
				otm.IdentityMatrix();
			GetGTessFunction();
			if (mSubDivideDisplacement && psGTessFunc) {
				// if we have a material that does displacement mapping and if we can do it
				Mesh *pMesh = new Mesh();
				needDelete = TRUE;
				(*psGTessFunc)((void *)&mesh, MAX_MESH, &otm, pMesh, NULL,
								&mDispApprox, &view, pMtl, FALSE, mSplitMesh);
				needDelete = TRUE;
				return pMesh;
			} else {
				Mesh *pMesh = new Mesh(mesh);
				needDelete = TRUE;

                BOOL hasUVs = pMesh->tvFace != NULL;
				pMesh->buildRenderNormals();

				// now displace the verts
				BitArray vertsSet;
				vertsSet.SetSize(pMesh->numVerts);

				for (int f = 0; f < pMesh->numFaces; f++) {
					Face *pFace = &pMesh->faces[f];
					TVFace *pTVFace = &pMesh->tvFace[f];
					int matid = pFace->getMatID();
					for (int v = 0; v < 3; v++) {
						int vidx = pFace->v[v];
						if (vertsSet[vidx])
							continue; // displace only once
						Point3 norm = pMesh->getNormal(vidx);
						norm.Normalize();
						Point3& vert = pMesh->getVert(vidx);

						UVVert uvvert;
                        if (hasUVs)
                            uvvert = pMesh->getTVert(pTVFace->t[v]);
                        else {
                            uvvert.x = 0.0;
                            uvvert.y = 0.0;
                        }

						pMesh->buildBoundingBox();
						Box3 bbox = pMesh->getBoundingBox();
						float dispScale = Length(bbox.pmax - bbox.pmin)/10.0f;

						float disp = GetDisp(pMtl, pMesh, f, pFace->getMatID(), vert, uvvert.x, uvvert.y, otm) * dispScale;
						vert += (norm * disp);
						vertsSet.Set(vidx);
					}
				}
				return pMesh;
			}
		}
	}

	needDelete = FALSE;
	return &mesh;
}
int	MaxExporter::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)
{

	/*if(!suppressPrompts)
		DialogBoxParam(hInstance, 
				MAKEINTRESOURCE(IDD_PANEL), 
				GetActiveWindow(), 
				MaxExporterOptionsDlgProc, (LPARAM)this);*/

	#pragma message(TODO("return TRUE If the file is exported properly"))

	Node::s_nextID = 1;
	ofstream myFile;
	myFile.open("DebugExporter.txt");
	wstring wFileName( name );
	string fileName( wFileName.begin(), wFileName.end() );
	//f= fopen( fileName.c_str(),"wb");
	BinaryFile = loadSave( fileName.c_str() );
	//BinaryFile.saveInt( 5 );
	//BinaryFile.close();
	myFile << "Start Export\n";

	IGameScene* gameScene = GetIGameInterface();
	gameScene->InitialiseIGame();
	int nodeCount = gameScene->GetTopLevelNodeCount();
	myFile << "Number of top level nodes: " << nodeCount << "\n";
	//get all of the materials
	for( int nodeNumber = 0; nodeNumber < nodeCount; ++nodeNumber)
	{
		IGameNode* gameNode = gameScene->GetTopLevelNode( nodeNumber );
		
		Node* myNode = new Node( gameNode );
		m_NodeList.push_back( myNode );
		findFaces( myNode, myFile );
		
	}

	myFile << "Number of materials\n";
	myFile << m_materialSet.size() << "\n";
	

	int totalBatches = 0;
	//myFile<< "Number of triangleBatchMaps: " << m_triangleBatchesPerNode.size() << "\n";
	for( auto nodeIter = m_NodeList.begin(); nodeIter != m_NodeList.end(); ++nodeIter )
	{
		std::map< IGameMaterial*, TriangleBatch* > triangleBatches = (*nodeIter)->m_triangleBatchesPerMaterial;
		myFile << "Invidiual triangleBatch size: " << triangleBatches.size() << "\n";

		for( auto materialIter = m_materialSet.begin(); materialIter != m_materialSet.end(); ++materialIter )
		{
			auto found = triangleBatches.find( * materialIter );
			if( found != triangleBatches.end() )
			{
				++totalBatches;
			}
		}
	}

	BinaryFile.saveInt( m_NodeList.size() );
	myFile << "Number of Nodes: " << m_NodeList.size() << "\n";
	
	for( auto nodeIter = m_NodeList.begin(); nodeIter != m_NodeList.end(); ++nodeIter )
	{
		std::map< IGameMaterial*, TriangleBatch* > triangleBatches = (*nodeIter)->m_triangleBatchesPerMaterial;
		std::map<IGameMaterial*, std::vector< NodeFace > > facesPerMaterial = (*nodeIter)->m_facesPerMaterial;
		IGameNode* currentNode = (*nodeIter)->m_gameNode;
		IGameNode* parentNode;
		GMatrix parentWTM;
		GMatrix toParentMatrix;
		GMatrix worldTM;
		GMatrix localTM;
		int time = gameScene->GetSceneStartTime();
		for( ; time < gameScene->GetSceneEndTime(); time += 4800/30 )
		{
			if( (*nodeIter)->m_parentID != 0 )
			{
				myFile << "Trying to find parent... \n";
				parentNode = (*nodeIter)->m_parent->m_gameNode;
				if( parentNode != nullptr )
				{
					myFile << "Parent found \n";
					parentWTM = parentNode->GetWorldTM( time );
					toParentMatrix = parentWTM.Inverse();

					worldTM = currentNode->GetWorldTM(  time ) * toParentMatrix;

				}

			}
			else
			{
				worldTM = currentNode->GetWorldTM( time );
				
			}
			(*nodeIter)->m_toParentMatrix.push_back( Matrix4x4( worldTM[0], worldTM[1], worldTM[2], worldTM[3] ) );
		}


		localTM = currentNode->GetWorldTM().Inverse();
		(*nodeIter)->m_worldToLocal = Matrix4x4(  localTM[0], localTM[1], localTM[2], localTM[3] );
		

		//Save the node
		BinaryFile.saveNode( *nodeIter, myFile );
		BinaryFile.saveInt( (*nodeIter)->m_triangleBatchesPerMaterial.size() );
	
		for( auto materialIter = m_materialSet.begin(); materialIter != m_materialSet.end(); ++materialIter )
		{
			//Set the current material's VBO and IBO
			//
			IGameMaterial* currentMaterial = *materialIter;
			TriangleBatch* currentBatch = triangleBatches[ currentMaterial ];
			
			GMatrix localTMNoTrans = localTM;
			localTMNoTrans.SetRow( 3, Point4( 0,0,0,1) );
			if( currentBatch != nullptr )
			{
				
				MaxMaterial* currentMaxMaterial = currentBatch->m_material;
				VBO* currentVBO = currentBatch->m_vbo;
				IBO* currentIBO = currentBatch->m_ibo;
				vector< NodeFace >& faceVector = facesPerMaterial.find( currentMaterial )->second;

				//Get texture materials and export them
				//
				if( currentMaterial != nullptr )
				{
					int numOfTexMaps = currentMaterial->GetNumberOfTextureMaps();
					myFile << "Number of texture maps: " << numOfTexMaps << "\n";
					for( int i = 0; i < numOfTexMaps; ++i )
					{
						IGameTextureMap* gameTextureMap = currentMaterial->GetIGameTextureMap( i );
						
						if( gameTextureMap != nullptr && gameTextureMap->IsEntitySupported() )
						{
							int stdMapSlot = gameTextureMap->GetStdMapSlot();
							if( stdMapSlot == ID_DI )
							{
								wstring wBitmapFileName;
								wBitmapFileName = gameTextureMap->GetBitmapFileName();
								if( wBitmapFileName.size() > 0 )
								{
									BitmapInfo bi( gameTextureMap->GetBitmapFileName() );
									BMMGetFullFilename( &bi );
									wBitmapFileName = bi.Name();
									std::string fullBitmapFileName( wBitmapFileName.begin(), wBitmapFileName.end() );
									if( fullBitmapFileName.size() > 0 )
									{
										int lastSlash = fullBitmapFileName.find_last_of('\\') + 1;
										if( lastSlash != string::npos )
										{
											const std::string bitmapFileName = fullBitmapFileName.substr( lastSlash );
											wstring nameAsWString( name );
											std::string nameAsString( nameAsWString.begin(), nameAsWString.end() );
											const std::string extension = nameAsString.substr( 0, nameAsString.find_last_of('\\') + 1 );
											std::string newFileName = extension;
											newFileName.append( bitmapFileName );
											wstring wNewFileName(newFileName.begin(), newFileName.end());
											if( CopyFile( wBitmapFileName.c_str(), wNewFileName.c_str(), false ) )
											{
												if( stdMapSlot == ID_DI )
												{
													currentMaxMaterial->m_diffuseTexture = bitmapFileName;
													currentMaxMaterial->bHasDiffuseTexture = true;
												}
											//BinaryFile.saveString( bitmapFileName );
											}
											else
											{
												myFile << GetLastError() << "\n";
												myFile << "copying the file FAILED.\n";
											}
										}
									}	
								}
							}
						}
					}
				}
				
				myFile<< "Number of faces for this material: " << faceVector.size() << "\n";
				for( int face = 0; face < faceVector.size(); ++face )
				{
					FaceEx* meshFace = faceVector[face].m_face;
					IGameMesh* gameMesh = faceVector[face].m_mesh;
					IGameSkin* gameSkin = gameMesh->GetIGameSkin();
					int position, normal, color, texCoordinate, maxPosition;
					for( int i = 0; i < 3; ++i)
					{
						
						maxPosition = (int)meshFace->vert[i];
						
						Point3 tempPos = gameMesh->GetVertex( maxPosition );
						tempPos = tempPos * localTM;
						Vector3D positionVec3( tempPos.x, tempPos.y, tempPos.z );
						position = currentVBO->insertPosition(positionVec3);

						normal = (int)meshFace->norm[i];
						Point3 tempNormal = gameMesh->GetNormal( normal );
						tempNormal = tempNormal * localTMNoTrans;
						tempNormal = tempNormal.Normalize();
						
						Vector3D normalVec3( tempNormal.x, tempNormal.y, tempNormal.z );
						normal = currentVBO->insertNormal(normalVec3);

						//IBO
						texCoordinate = (int)meshFace->texCoord[i];
						Point2 tempTexCoord = gameMesh->GetTexVertex( texCoordinate );
						Vector2 texCoordVec2( tempTexCoord.x, tempTexCoord.y );
						texCoordinate = currentVBO->insertTexCoord(texCoordVec2);
						VertexIndex VI( position, normal, texCoordinate );
						if( gameSkin != nullptr )
						{
							int numberOfBones = gameSkin->GetNumberOfBones( maxPosition );
							for( int boneIndex = 0; boneIndex < numberOfBones; ++boneIndex )
							{
								float boneWeight = gameSkin->GetWeight( maxPosition, boneIndex );
								IGameNode* bone = gameSkin->GetIGameBone( maxPosition, boneIndex );
								myFile << "Bone node ID: " << bone->GetNodeID() << "\n";
								int nodeIDForBone = m_boneIDToNodeID[ bone->GetNodeID() ];
								myFile << "Node ID: " << nodeIDForBone << "\n";
								VI.addBoneWeight( nodeIDForBone, boneWeight );

								/*for( auto boneIter = m_NodeList.begin(); boneIter != m_NodeList.end(); ++boneIter )
								{
									if( (*boneIter)->m_gameNode == bone )
									{
										myFile << "Found the bone!\n"; 
										
									}
								}*/
								
							}
							VI.topBoneWeights();
						}

						int vertIndex = currentVBO->insertVertex( VI );
						currentIBO->addIndex( vertIndex );

					}

				}
				
				BinaryFile.saveTriangleMesh( currentBatch, myFile );
			}
		}

	}
	myFile.close();

	for( int nodeNumber = 0; nodeNumber < nodeCount; ++nodeNumber)
	{
		IGameNode* gameNode = gameScene->GetTopLevelNode( nodeNumber );
		if( gameNode != nullptr )
		{
			tearDown( gameNode );
		}
		
	}

	BinaryFile.close();
	return TRUE;

	//return FALSE;
}