Exemple #1
0
void MultiDLA::density(double density, double& denAero, double& porosity) const
{
    if (m_finished) {
        // calc
        double volume = 0.0;
        int32_t sx = m_fld->size().coord(0);
        int32_t sy = m_fld->size().coord(1);
        int32_t sz = m_fld->size().coord(2);
        MCoord::setDefDims(3);
        MCoord sc;
        for (size_t i = 0; i < 3; ++i) {
            sc.setCoord(i, m_fld->size().coord(i));
        }
        CellsField* cf = new CellsField(sc, MCoord(), 2 * m_fld->radius());
        for (int32_t ix = 0; ix < sx; ++ix) {
            for (int32_t iy = 0; iy < sy; ++iy) {
                for (int32_t iz = 0; iz < sz; ++iz) {
                    if (m_fld->element(MCoord(ix, iy, iz)) == OCUPIED_CELL) {
                        MCoord currCoord(ix, iy, iz);
                        cf->setElement(currCoord);
                        volume += vAdd(cf, currCoord);
                    }
                }
            }
        }
        delete cf;
        double aeroVolume = volume / (sx * sy * sz);
        porosity = 1.0 - aeroVolume;
        denAero = density * aeroVolume;
    }
}
Exemple #2
0
bool hitTriang(Photon *photon, Triang *triang, const float distance, const Material *materials)
{
    Shader shader = DIFFUSE;

    // Better idea?
    if (fDot(triang->direct, photon->direct) > -EPSILON)
        triang->direct = vNeg(triang->direct);

    // Update ray's position to the point where the ray hits the sphere
    photon->origin = fFMA(photon->direct, distance - UM(10), photon->origin);
    photon->lambda = materials[triang->mID].lambda;

    if (shader == CRAZY) {
        photon->direct = vNorm(vSub(newVec(0.99, 0, 0), photon->origin));
        return REFLECTED;
    }

    else if (shader == SPECULAR) {
        // Angle between new and old vector is twice the angle between old vector and normal
        Vec reflect = vDot(photon->direct, triang->direct);
        photon->direct = vSub(photon->direct, vMul(triang->direct, vAdd(reflect, reflect)));

        return REFLECTED;
    }

    else if (shader == DIFFUSE) {
        photon->direct = randDir();
        if (fDot(photon->direct, triang->direct) < EPSILON)
            photon->direct = vNeg(photon->direct);

        return REFLECTED;
    }

    else return ABSORBED;
}
Exemple #3
0
void IMU::orthonormalize(float inputDCM[3][3]) {
    // Takes 700 us.
    // Orthogonalize the i and j unit vectors (DCMDraft2 Eqn. 19).
    errDCM = vDotP(inputDCM[0], inputDCM[1]);
    vScale(inputDCM[1], -errDCM/2, dDCM[0]);   // i vector correction
    vScale(inputDCM[0], -errDCM/2, dDCM[1]);   // j vector correction
    vAdd(inputDCM[0], dDCM[0], inputDCM[0]);
    vAdd(inputDCM[1], dDCM[1], inputDCM[1]);

    // k = i x j
    vCrossP(inputDCM[0], inputDCM[1], inputDCM[2]);

    // Normalize all three vectors.
    vNorm(inputDCM[0]);
    vNorm(inputDCM[1]);
    vNorm(inputDCM[2]);
}
Exemple #4
0
Photon triangEmit(const Triang *triang, const Material *materials)
{
    Photon p;
    float u = drand48(), v = drand48();
    Vec point = vAdd(fMul(triang->vectab, u), fMul(triang->vectac, v));

    // If point is outside triangle
    if (!triang->rectan && u + v < EPSILONONE)
        p.origin = vSub(vAdd(triang->origin, vAdd(triang->vectab, triang->vectac)), point);
    else
        p.origin = vAdd(triang->origin, point);

    p.direct = randDir();
    if (fDot(p.direct, triang->direct) > EPSILON)
        p.direct = vNeg(p.direct);

    p.lambda = materials[triang->mID].lambda;
    return p;
}
Exemple #5
0
Intersect Triangle::intersect(Ray r) {
	Intersect::Intersect ret = *new Intersect::Intersect();
	float a = v1.getX() - v2.getX();
	float b = v1.getY() - v2.getY();
	float c = v1.getZ() - v2.getZ();
	float d = v1.getX() - v3.getX();
	float e = v1.getY() - v3.getY();
	float f = v1.getZ() - v3.getZ();
	float g = r.getDir().at(0);
	float h = r.getDir().at(1);
	float i = r.getDir().at(2);
	float j = v1.getX() - r.getEye().at(0);
	float k = v1.getY() - r.getEye().at(1);
	float l = v1.getZ() - r.getEye().at(2);
	float eiminushf = e*i - h*f;
	float gfminusdi = g*f - d*i;
	float dhminuseg = d*h - e*g;
	float akminusjb = a*k - j*b;
	float jcminusal = j*c - a*l;
	float blminuskc = b*l - k*c;
	float m = a*(eiminushf) + b*(gfminusdi) + c*(dhminuseg);
	float beta = (j*(eiminushf) + k*(gfminusdi) + l*(dhminuseg))/m;
	if (beta < 0) {return ret;}
	float gamma = (i*(akminusjb) + h*(jcminusal) + g*(blminuskc))/m;
	if (gamma < 0 || beta+gamma > 1) {return ret;}
	float t = (-1)*(f*(akminusjb) + e*(jcminusal) + d*(blminuskc))/m;
	std::vector<float> p;
	
	std::vector<float> vec1 = v1.toVec();
	std::vector<float> vec2 = v2.toVec();
	std::vector<float> vec3 = v3.toVec();
	std::vector<float> sub1 = vSub(&vec2, &vec1);
	std::vector<float> sub2 = vSub(&vec3, &vec1);
	std::vector<float> scaled1 = vScale(&beta, &sub1);
	std::vector<float> scaled2 = vScale(&gamma, &sub2);
	std::vector<float> added1 = vAdd(&vec1, &scaled1);
	p = vAdd(&added1, &scaled2);
	
	ret.setPoint(p);
	
	return ret;
}
Exemple #6
0
double MultiDLA::surfaceArea(double density, uint32_t steps) const
{
    double result = 0.0;
    if (m_finished) {
#ifndef _WIN32
        uint32_t t0 = uint32_t(clock());
#endif
        // calc
        double volume = 0.0;
        double square = 0.0;
        int32_t sx = m_fld->size().coord(0);
        int32_t sy = m_fld->size().coord(1);
        int32_t sz = m_fld->size().coord(2);
        MCoord::setDefDims(3);
        MCoord sc;
        for (size_t i = 0; i < 3; ++i) {
            sc.setCoord(i, m_fld->size().coord(i));
        }
        CellsField* cf = new CellsField(sc, MCoord(), 2 * m_fld->radius());
        double cellRadius = cf->radius();
        for (int32_t ix = 0; ix < sx; ++ix) {
            for (int32_t iy = 0; iy < sy; ++iy) {
                for (int32_t iz = 0; iz < sz; ++iz) {
                    if (m_fld->element(MCoord(ix, iy, iz)) == OCUPIED_CELL) {
                        MCoord currCoord(ix, iy, iz);
                        cf->setElement(currCoord);
                        volume += vAdd(cf, currCoord) * cube(cf->side());
                        square += SfromR(cellRadius);
                    }
                }
            }
        }
        delete cf;
        // -> Monte-Carlo
        uint32_t positive = m_fld->monteCarlo(steps);
        result = 1000000 * square * positive / (steps * density * volume);
#ifndef _WIN32
        std::cout << "Прошло: " << double(clock() - t0) / CLOCKS_PER_SEC << " сек." << std::endl;
#endif
    }
    return result;
}
Exemple #7
0
double intersectRectan(Rectan *rectan, Photon *photon)
{   
    // Clipping
    double dotProduct = vDotp(photon->direct, rectan->direct);
    if (dotProduct < EPSILON && dotProduct > -EPSILON) return MISS;
    
    // For explanation, see intersectCamera 
    Vec vec = vSub(rectan->origin, photon->origin);
    double dist = vDotp(rectan->direct, vec) / dotProduct;
        
    if (dist < EPSILON) return MISS;
    
    /**************/
    
    // Hit point on plane
    Vec point = vMul(photon->direct, dist);
    point = vAdd(photon->origin, point);
    point = vSub(point, rectan->origin);
    
    // Compute dot products
    double dotAA = vDotp(rectan->vectab, rectan->vectab);
    double dotBB = vDotp(rectan->vectad, rectan->vectad);
    double dotAB = vDotp(rectan->vectab, rectan->vectad);
    double dotAP = vDotp(rectan->vectab, point);
    double dotBP = vDotp(rectan->vectad, point);
    
    // Compute barycentric coordinates
    double denominator = 1 / (dotAA * dotBB - dotAB * dotAB);
    double u = (dotBB * dotAP - dotAB * dotBP) * denominator;
    double v = (dotAA * dotBP - dotAB * dotAP) * denominator;
    
    // Check if point is in rectangle
    if (u < EPSILON || v < EPSILON || u > EPSILONONE || v > EPSILONONE)
        return MISS;
    
    return dist;
}
Exemple #8
0
void handleInput(GameState* gs, InputState* is) {
	
	double te = gs->frameSpan;
	
	float moveSpeed = gs->settings.keyScroll * te; // should load from config
	float rotateSpeed = gs->settings.keyRotate * te; // 20.8 degrees
	float keyZoom = gs->settings.keyZoom * te;
	float mouseZoom = gs->settings.mouseZoom * te;
	
	if(is->clickButton == 1) {
		/*
		flattenArea(gs->map.tb,
			gs->cursorPos.x - 5,
			gs->cursorPos.y - 5,
			gs->cursorPos.x + 5,
			gs->cursorPos.y + 5
		);
		
		setZone(&gs->map,
			gs->cursorPos.x - 5,
			gs->cursorPos.y - 5,
			gs->cursorPos.x + 5,
			gs->cursorPos.y + 5,
			gs->activeTool + 1
		);
		
		
		checkMapDirty(&gs->map);
		*/
	}
	
	if(is->buttonDown == 1) {
		gs->mouseDownPos.x = gs->cursorPos.x;
		gs->mouseDownPos.y = gs->cursorPos.y;
		printf("start dragging at (%d,%d)\n", (int)gs->cursorPos.x, (int)gs->cursorPos.y);
	}
	if(is->buttonUp == 1) {
		//vCopy(&gs->cursorPos, &gs->mouseDownPos);
		printf("stopped dragging at (%d,%d)\n", (int)gs->cursorPos.x, (int)gs->cursorPos.y);
	}
	
	if(is->clickButton == 2) {
		gs->activeTool = (gs->activeTool + 1) % 3;
	}
	
	// look direction
	if(is->keyState[38] & IS_KEYDOWN) {
		gs->direction += rotateSpeed;
	}
	if(is->keyState[39] & IS_KEYDOWN) {
		gs->direction -= rotateSpeed;
	}
	// keep rotation in [0,F_2PI)
	gs->direction = fmodf(F_2PI + gs->direction, F_2PI);
	
	// zoom
	if(is->keyState[52] & IS_KEYDOWN) {
		gs->zoom += keyZoom;
 		gs->zoom = fmin(gs->zoom, -10.0);
	}
	if(is->keyState[53] & IS_KEYDOWN) {
		gs->zoom -= keyZoom;
	}
	if(is->clickButton == 4) {
		gs->zoom += mouseZoom;
 		gs->zoom = fmin(gs->zoom, -10.0);
	}
	if(is->clickButton == 5) {
		gs->zoom -= mouseZoom;
	}

	// movement
	Vector move = {
		.x = moveSpeed * sin(F_PI - gs->direction),
		.y = moveSpeed * cos(F_PI - gs->direction),
		.z = 0.0f
	};
	
	if(is->keyState[111] & IS_KEYDOWN) {
		vAdd(&gs->lookCenter, &move, &gs->lookCenter);
	}
	if(is->keyState[116] & IS_KEYDOWN) {
		vSub(&gs->lookCenter, &move, &gs->lookCenter);
	}
	
	// flip x and y to get ccw normal, using move.z as the temp
	move.z = move.x;
	move.x = -move.y;
	move.y = move.z;
	move.z = 0.0f;
	
	if(is->keyState[113] & IS_KEYDOWN) {
		vSub(&gs->lookCenter, &move, &gs->lookCenter);
	}
	if(is->keyState[114] & IS_KEYDOWN) {
		vAdd(&gs->lookCenter, &move, &gs->lookCenter);
	}
	
	if(is->keyState[110] & IS_KEYDOWN) {
		nearPlane += 50 * te;
		printf("near: %f, far: %f\n", nearPlane, farPlane);
	}
	if(is->keyState[115] & IS_KEYDOWN) {
		nearPlane -= 50 * te;
		printf("near: %f, far: %f\n", nearPlane, farPlane);
	}
	if(is->keyState[112] & IS_KEYDOWN) {
		farPlane += 250 * te;
		printf("near: %f, far: %f\n", nearPlane, farPlane);
	}
	if(is->keyState[117] & IS_KEYDOWN) {
		farPlane -= 250 * te;
		printf("near: %f, far: %f\n", nearPlane, farPlane);
	}
	
	static lastChange = 0;
	if(is->keyState[119] & IS_KEYDOWN) {
		if(gs->frameTime > lastChange + 1) {
			gs->debugMode = (gs->debugMode + 1) % 5;
			lastChange = gs->frameTime;
		}
	}
	
}


void setGameSettings(GameSettings* g, UserConfig* u) {
	
	const float rotateFactor = 0.7260f;
	const float scrollFactor = 300.0f;
	const float zoomFactor = 600.0f;
	
	g->keyRotate = rotateFactor * fclampNorm(u->keyRotateSensitivity);
	g->keyScroll = scrollFactor * fclampNorm(u->keyScrollSensitivity);
	g->keyZoom = zoomFactor * fclampNorm(u->keyZoomSensitivity);
	
	g->mouseRotate = rotateFactor * fclampNorm(u->mouseRotateSensitivity);
	g->mouseScroll = scrollFactor * fclampNorm(u->mouseScrollSensitivity);
	g->mouseZoom = 4 * zoomFactor * fclampNorm(u->mouseZoomSensitivity);
	
	printf("keyRotate %.3f\n", g->keyRotate);
	printf("keyScroll %.3f\n", g->keyScroll);
	printf("keyZoom %.3f\n", g->keyZoom);
	printf("mouseRotate %.3f\n", g->mouseRotate);
	printf("mouseScroll %.3f\n", g->mouseScroll);
	printf("mouseZoom %.3f\n", g->mouseZoom);
	
}


void setUpView(GameState* gs) {
	
	
}



void depthPrepass(XStuff* xs, GameState* gs, InputState* is) {
	
	// draw UI
	renderUIPicking(xs, gs);
	
	
	// draw terrain
	// TODO: factor all the math into the frame setup function
	//mScale3f(10, 10, 10, &mModel);
	//mRot3f(0, 1, 0, gs->direction, &mModel);
	msPush(&gs->proj);
	msPerspective(60, gs->screen.aspect, nearPlane, farPlane, &gs->proj);

	
	msPush(&gs->view);
	
	
	
	// order matters! don't mess with this.
	msTrans3f(0, -1, gs->zoom, &gs->view);
	msRot3f(1, 0, 0, F_PI / 6, &gs->view);
	msRot3f(0,1,0, gs->direction, &gs->view);
	msTrans3f(-gs->lookCenter.x, 0, -gs->lookCenter.y, &gs->view);
	
	// y-up to z-up rotation
	msRot3f(1, 0, 0, F_PI_2, &gs->view);
	msScale3f(1, 1, -1, &gs->view);


	
	
	// calculate cursor position
	Vector eyeCoord;
	Vector worldCoord;
	Matrix p, invp, invv;
	
	// device space (-1:1)
	Vector devCoord;
	devCoord.x = 0.50;
	devCoord.y = 0.50;
	devCoord.z = -1.0;
	
	// eye space
	mInverse(msGetTop(&gs->proj), &invp);
	vMatrixMul(&devCoord, &invp, &eyeCoord);
	vNorm(&eyeCoord, &eyeCoord);
	
	// world space
	mInverse(msGetTop(&gs->view), &invv);
	vMatrixMul(&eyeCoord, &invv, &worldCoord);
	vNorm(&worldCoord, &worldCoord);

	// draw terrain
// 	drawTerrainBlockDepth(&gs->map, msGetTop(&gs->model), msGetTop(&gs->view), msGetTop(&gs->proj));
	drawTerrainDepth(&gs->map, msGetTop(&gs->view), msGetTop(&gs->proj), &gs->screen.wh);
	
	msPop(&gs->view);
	msPop(&gs->proj);
	
}
Exemple #9
0
bool hitRectan(Photon *photon, Rectan *rectan, double distance)
{
    // Specular reflection
    if (true) {
        // Update ray's position to the point where the ray hits the sphere
        Vec vec = vMul(photon->direct, distance);
        photon->origin = vAdd(photon->origin, vec);
        
        // Angle between new and old vector is twice the angle between old vector and normal
        vec = vMul(rectan->direct, vDotp(photon->direct, rectan->direct) * 2.f);
        vec = vSub(rectan->direct, photon->direct);
        photon->direct = vNorm(vec);
        
        // Might not be necessary...
        vec = vMul(photon->direct, 1000.f * EPSILON);
        photon->origin = vAdd(photon->origin, vec);
        
        return REFLECTED;
    }
    
    // Diffuse reflection
    else if (false) {
        // Necessary for adjusting direction of reflected photon later on
        bool positiveAngle = NO;
        if (vDotp(photon->direct, rectan->direct) > EPSILON) positiveAngle = YES;
        
        // Update ray's position to the point where the ray hits the sphere
        Vec vec = vMul(photon->direct, distance);
        photon->origin = vAdd(photon->origin, vec);
        
#warning DEBUG!!!
        // Camera origin
        /*Vec origin; origin.x = 0.99f; origin.y = 0.f; origin.z = 0.f;
         Vec newDir; newDir = vSub(&origin, &photon->origin);
         photon->direct = vNorm(&newDir);*/
        
        // Using spherical coordinate system to guarantee
        // uniform distribution of orientations in space
        double azimuth = drand48() * M_PI * 2;         // "phi"
        double inclination = acos(2 * drand48() - 1);  // "theta"
        photon->direct.x = sin(inclination) * cos(azimuth);
        photon->direct.y = sin(inclination) * sin(azimuth);
        photon->direct.z = cos(inclination);
        
        // Adjusting direction of reflected photon
        // Incoming positive -> negative outgoing
        // Incomi ng negative -> positive outgoing
        if (positiveAngle) {
            if (vDotp(photon->direct, rectan->direct) > EPSILON)
                photon->direct = vMul(photon->direct, -1.f);
        }
        else if (vDotp(photon->direct, rectan->direct) < -EPSILON)
            photon->direct = vMul(photon->direct, -1.f);
        
        photon->direct = vNorm(photon->direct);
        
        // Might not be necessary...
        vec = vMul(photon->direct, 1000.f * EPSILON);
        photon->origin = vAdd(photon->origin, vec);
        
        // Color
        photon->wavelength = rectan->mID;
        
        return REFLECTED;
    }
    
    /*
     * Absorption
     */
    else return ABSORBED;
}
Exemple #10
0
void MultiDLA::cMultiDLA(CellsField* fld, double targetPorosity, uint32_t initN,
                         uint32_t step, uint32_t hitCnt)
{
    fld->clear();

    double currVol = 0.0;
    double needVol = fld->cellsCnt() * (1 - targetPorosity);
    
    bool needHit = (hitCnt != 1);
    
    size_t dimensions = MCoord::defDims();
    
    MCoordVec* mapNeigh = createNeighborsMap(dimensions);
    MCoordVec* mapSteps = createStepMap(dimensions, step);
    
    uint32_t currCnt = 0;
    MCoord currCoord;
    
    while (currCnt != initN) {
        currCoord = freeRandomPntInField(fld);
        fld->setElement(currCoord);
        currVol += vAdd(fld, currCoord);
        ++currCnt;
    }
    
    CellsField* hitField;
    if (needHit) {
        hitField = new CellsField(fld->size(), MCoord(), fld->radius() * 2);
    }
    
    while (currVol < needVol) {
        currCoord = freeRandomPntInField(fld);
        if (needHit) {
            hitField->clear();
        }
        while (true) {
            if (!fld->isSet(currCoord) && cntNeighbors(fld, mapNeigh, currCoord) != 0) {
                FieldElement newHitCnt = 1;
                if (needHit) {
                    newHitCnt = hitField->elementVal(currCoord) + 1;
                    hitField->setElementVal(currCoord, newHitCnt);
                }
                
                if (newHitCnt >= hitCnt) {
                    fld->setElement(currCoord);
                    currVol += vAdd(fld, currCoord);
                    ++currCnt;
                    break;
                }
            }
            
            MCoord tmpCoord = makeStep(currCoord, mapSteps);
            tmpCoord = toroidizeCoords(tmpCoord, fld->size());
            while (fld->isSet(tmpCoord)) {
                tmpCoord = makeStep(currCoord, mapSteps);
                tmpCoord = toroidizeCoords(tmpCoord, fld->size());
            }
            currCoord = tmpCoord;
        }
    }
    
    delete mapNeigh;
    mapNeigh = nullptr;
    delete mapSteps;
    mapSteps = nullptr;
    if (needHit) {
        delete hitField;
        hitField = nullptr;
    }
}
Exemple #11
0
/************************************************************************************************
* Bouncher moving                                                                               *
************************************************************************************************/
void cBouncher::Move(float mx, float my, float mz)
{
    this->Pos = vAdd(this->Pos, vInit(mx, my, mz));
}
Exemple #12
0
/************************************************************************************************
* Move ball forward                                                                             *
************************************************************************************************/
void cBall::MoveForward()
{
    this->Pos = vAdd(this->Pos, vScale(this->Dir, this->Vel));
}
Exemple #13
0
//===============================================
//     Unit Tests
//===============================================
int main() {
    // set for command line argument -t to run unit tests.
    bool test = true;

    if (test) {
        std::cout<<"\n=================\nBegin UNIT TESTS\n=================\n\n";
        Light::Light n = *new Light::Light(0, 1, 1, 0, 0.5, 0.5, 0.5);
        n.print();

        Intersect::Intersect i = *new Intersect::Intersect();
        if(i.isHit()) {
            std::cout<<"INCORRECT! hit is true.\n\n";
        }
        else {
            std::cout<<"CORRECT! hit is false.\n\n";
            i.setHit(true);
        }
        if(i.isHit()) {
            std::cout<<"CORRECT! hit is true.\n\n";
        }
        else {
            std::cout<<"INCORRECT! hit is false.\n\n";
        }
        std::vector<float> ptest(3);
        ptest[0] = 0;
        ptest[1] = 1;
        ptest[2] = 2;
        i.setPoint(ptest);
        std::vector<float> p = i.getPoint();
        std::cout<< "[" << p[0] << ", " << p[1] << ", " << p[2] << "]\n";

        Vertex::Vertex a = *new Vertex::Vertex(0,0,0);
        Vertex::Vertex b = *new Vertex::Vertex(1,0,0);
        Vertex::Vertex c = *new Vertex::Vertex(0,1,0);
        a.print();
        a = a.sub(b);
        a.print();
        std::vector<float> d = c.toVec();
        std::cout<<"vec ["<< d[0] << ", " << d[1] << ", " << d[2] << "]\n";
        Vertex::Vertex e1 = *new Vertex::Vertex(d);
        e1.print();
        Vertex a1 = *new Vertex::Vertex(0,1,0);
        Vertex b1 = *new Vertex::Vertex(1,-1,0);
        Vertex c1 = *new Vertex::Vertex(-1,-1,0);
        Triangle t = *new Triangle::Triangle(a1,b1,c1);
        p[0] = 0;
        p[1] = 0;
        p[2] = 0;
        std::vector<float> e(3);
        e[0] = 0;
        e[1] = 0;
        e[2] = 3;

        Ray::Ray r = *new Ray::Ray(e, p);
        i = t.intersect(r);
        if (i.isHit()) {
            std::cout<<"Triangle Intersected - OKAY\n";
        }
        Sphere::Sphere s = *new Sphere::Sphere(1, p);
        if (s.intersect(r).isHit()) {
            std::cout<<"Sphere Intersected - OKAY\n";
        }


        e[0] = 0;
        e[1] = -4;
        e[2] = -4;
        p[0] = 1;
        p[1] = 1;
        p[2] = -1;
        r.setEye(e);
        r.setPoint(p);
        std::cout<<"projected ";
        vPrint(r.project(1.5));


        PPM* ppm = new PPM(640, 480, 255);
        int val;
        for (float h = 0; h<480; h++) {
            for (float w =0; w<640; w++) {
                val = h;//std::min(255, (int)((w/639)*255.0f));
                ppm->addPixel(*(new Pixel::Pixel(val, val, val)));
            }
        }
        ppm->save("output");
        /*
        for (float h = 0; h < 3; h++) {
        	for (float w = 0; w< ppm->getW(); w++) {
        		std::cout<<w<<" ";
        		ppm->getPixel(w, h).print();
        	}
        }
        */

        std::cout<<"End PPM tests\n";
        Pixel::Pixel px = *new Pixel::Pixel(255, 255, 255);
        Pixel::Pixel black = *new Pixel::Pixel(0,0,0);
        Pixel::Pixel pfloat = *new Pixel::Pixel(1.0f, 0.9f, 0.05f);
        Pixel::Pixel pmax = *new Pixel::Pixel(2.0f, 1.0f, 0.5f);
        px.print();
        black.print();
        black.add(px);
        black.print();
        pfloat.print();
        pmax.print();


        std::vector<float> test1(3);
        test1[0] = 1;
        test1[1] = 0;
        test1[2] = 0.5;
        std::vector<float> test2(3);
        test2[0] = 0;
        test2[1] = 1;
        test2[2] = 0.5;
        std::cout<<vDot(test1, test2)<<"\n";
        vPrint(vSub(test1, test2));
        vPrint(vAdd(test1, test2));
        vPrint(vMult(test1, test2));
        vPrint(normalize(test1));
        vPrint(normalize(test2));
        vPrint(vCross(test1, test2));
        vPrint(vScale(-1, test1));

        std::cout<<"\n=================\nEnd UNIT TESTS\n=================\n\n";

        return 0;
    }
    else {
        return 0;
    }
}