Exemple #1
0
bool line_polyHit (const LINE3 * const line, int points, const VECTOR3 * const poly, float * tAtIntersection)
{
	VECTOR3
		u, v,
		plane,
		hit;
	LINE3
		transLine;
	float
		t;
	u = vectorSubtract (&poly[1], &poly[0]);
	v = vectorSubtract (&poly[2], &poly[0]);
	plane = vectorCross (&u, &v);
	plane = vectorNormalize (&plane);

	// see note in the line_triHit function
	transLine.origin = vectorSubtract (&line->origin, &poly[0]);
	transLine.dir = line->dir;
	if (!line_planeHit (&transLine, &plane, &t))
		return false;
	hit = vectorCreate
	(
		line->origin.x + line->dir.x * t,
		line->origin.y + line->dir.y * t,
		line->origin.z + line->dir.z * t
	);
	if (pointInPoly (&hit, points, poly))
	{
		if (tAtIntersection)
			*tAtIntersection = t;
		return true;
	}
	return false;
}
Exemple #2
0
static REAL triangleArea2( const BVector *vertexA, const BVector *vertexB, const BVector *vertexC )
{
	BVector ab, ac;
	vectorSubtract( vertexB, vertexA, &ab );
	vectorSubtract( vertexC, vertexA, &ac );
	return vectorCrossProduct( &ac, &ab );
}
Exemple #3
0
void OBJ_GenerateLightingInfo(obj_t* obj)
{
	vec3_t v1,v2 ;
	int i;
	vec2_t st1,st2;
	float coef;
	vec3_t currentTangent;
	vec3_t currentNormal;
	vec3_t* tangents;
	vec3_t* normals;
	
	tangents = (vec3_t*)calloc(obj->num_vertices, sizeof(vec3_t));
	normals  = (vec3_t*)calloc(obj->num_vertices, sizeof(vec3_t));
	

	
	//Accumulate tangents & normals
	for(i=0;i<obj->num_indices/3;i++)
	{
		vectorSubtract(obj->vertices[obj->indices[i*3+2]].position , obj->vertices[obj->indices[i*3]].position, v1);
		vectorSubtract(obj->vertices[obj->indices[i*3+1]].position , obj->vertices[obj->indices[i*3]].position, v2);
		
		vector2Subtract(obj->vertices[obj->indices[i*3+2]].textCoo,obj->vertices[obj->indices[i*3]].textCoo,st1);
		vector2Subtract(obj->vertices[obj->indices[i*3+1]].textCoo,obj->vertices[obj->indices[i*3]].textCoo,st2);
	
		//Normal part
		vectorCrossProduct(v2, v1, currentNormal);
		vectorAdd(normals[obj->indices[i*3+0]],currentNormal,normals[obj->indices[i*3+0]]);
		vectorAdd(normals[obj->indices[i*3+1]],currentNormal,normals[obj->indices[i*3+1]]);
		vectorAdd(normals[obj->indices[i*3+2]],currentNormal,normals[obj->indices[i*3+2]]);
		
		//Tangent part
		coef = 1/ (st1[0] * st2[1] - st2[0] * st1[1]);
		
		currentTangent[0] = coef * (v1[0] * st2[1]  + v2[0] * -st1[1]);
		currentTangent[1] = coef * (v1[1] * st2[1]  + v2[1] * -st1[1]);
		currentTangent[2] = coef * (v1[2] * st2[1]  + v2[2] * -st1[1]);
		
		vectorAdd(tangents[obj->indices[i*3+0]],currentTangent,tangents[obj->indices[i*3+0]]);
		vectorAdd(tangents[obj->indices[i*3+1]],currentTangent,tangents[obj->indices[i*3+1]]);
		vectorAdd(tangents[obj->indices[i*3+2]],currentTangent,tangents[obj->indices[i*3+2]]);
	}
	
	//Vector Normalize + Normalize
	for(i=0;i<obj->num_vertices;i++)
	{
		normalize(tangents[i]);
		vectorScale(tangents[i],DE_SHRT_MAX,obj->vertices[i].tangent);
		
		normalize(normals[i]);
		vectorScale(normals[i],DE_SHRT_MAX,obj->vertices[i].normal);
	}
	
	free(tangents);
	free(normals);
}
Exemple #4
0
// init data
bool Terrain::init (const char *filename) {
    // try to load map
    printf ("\nLOADING TERRAIN...\n", filename);
    printf ("\tMap file: %s\n", filename);
    if (!loadHeightMap (filename))
        return false;

    int v_index = 0;					// index for vertex array
    int n_index = 0;					// index for normal array
    float x, z;							// temp coord

    SDL_LockSurface(map_h);
    size = map_h -> w;

    num_vert = (long) (map_h -> w * map_h -> h * 4 / (res * res));
    vertex = new Vector[num_vert];			// allocate vertex memory
    texcoord = new TexCoord[num_vert];		// allocate texture memory
    num_normal = (long) (map_h -> w * map_h -> h / (res * res));
    normal = new Vector[num_normal];			// allocate normal memory
    printf ("\tVertex num: %d\n", num_vert);

    // loop for init vertex
    for (int i = 0; i < map_h -> w; i += (int) res) {			// width
        for (int j = 0; j < map_h -> h; j += (int) res) {		// height
            for (int n_tri = 0; n_tri < 4; n_tri++) {				// polygon
                // x, y
                x = (float) i + ( ( n_tri == 1 || n_tri == 2) ? res : 0.0f );
                z = (float) j + ( ( n_tri == 2 || n_tri == 3) ? res : 0.0f );

                // set vertex
                vertex[v_index].x = (x - ( map_h -> w / 2 ));
                vertex[v_index].z = (z - ( map_h -> h / 2 ));
                vertex[v_index].y = getHeightFromMap (x, z);

                // set texture coord
                texcoord[v_index].u = x / map_h -> w;
                texcoord[v_index].v = z / map_h -> h;

                v_index++;			// go to next vertex
            }
            // calculate normal coord
            Vector ab, bc;
            vectorSubtract (vertex[v_index-3], vertex[v_index-2], ab);
            vectorSubtract (vertex[v_index-2], vertex[v_index-1], bc);
            crossProduct (ab, bc, normal[n_index]);
            normalize (normal[n_index]);

            n_index++;
        }
    }
    SDL_UnlockSurface(map_h);

    return true;
}
Exemple #5
0
float *faceNormal(float *vectA, float *vectB, float *vectC)
{
	float *result;
	float *vectD;
	float *vectE;

	vectD = vectorSubtract(vectB, vectA, 3);
	vectE = vectorSubtract(vectC, vectA, 3);
	result = vectorCrossProduct(vectD, vectE);
	delete []vectD;
	delete []vectE;
	return result;
}
Exemple #6
0
bool pointInPoly (const VECTOR3 * const point, int points, const VECTOR3 * const poly)
{
	VECTOR3
		u, v,
		plane;
	enum dim_drop
		drop;
	int
		i = 0,
		side,
		sideMatch = 10;
	float
		x, y,
		px[2], py[2];
	if (points < 3)
		return false;
	u = vectorSubtract (&poly[1], &poly[0]);
	v = vectorSubtract (&poly[2], &poly[0]);
	plane = vectorCross (&u, &v);
	drop =
		(fabs(plane.x) > fabs(plane.y))
			? (fabs(plane.x) > fabs(plane.z))
				? DROP_X
				: DROP_Z
			: (fabs(plane.y) > fabs(plane.z))
				? DROP_Y
				: DROP_Z;

	//printf ("dropping %c\n", drop == DROP_X ? 'X' : drop == DROP_Y ? 'Y' : 'Z');
	x = (drop == DROP_X) ? point->y : point->x;
	y = (drop == DROP_Z) ? point->y : point->z;
	px[1] = (drop == DROP_X) ? poly[points-1].y : poly[points-1].x;
	py[1] = (drop == DROP_Z) ? poly[points-1].y : poly[points-1].z;
	while (i < points)
	{
		px[0] = px[1];
		py[0] = py[1];
		px[1] = (drop == DROP_X) ? poly[i].y : poly[i].x;
		py[1] = (drop == DROP_Z) ? poly[i].y : poly[i].z;
		side = turns (x, y, px[0], py[0], px[1], py[1]);

		//printf ("%.2f, %.2f vs. %.2f, %.2f -> %.2f, %.2f: %c\n", x, y, px[0], py[0], px[1], py[1], d == RIGHT ? 'R' : d == LEFT ? 'L' : 'T');

		if (sideMatch != 10 && side != sideMatch)
			return false;
		sideMatch = side;
		i++;
	}
	return true;
}
// If the ray intersects the sphere, return nearest distance along ray at which
// it happens. If it doesn't, return -1
int sphereIntersection(struct Sphere sphere, struct Ray ray)
{
    // The intersection algorithm assumes that the ray starts at the origin,
    // so translate the sphere first.
    sphere.position = vectorSubtract(sphere.position, ray.origin);

    int directionDotPosition = \
        vectorUnitDotProduct2(sphere.position, ray.direction);
    int sqrtTerm = fp_mult(directionDotPosition,directionDotPosition) \
                    - vectorDotProduct(sphere.position, sphere.position) \
                    + fp_mult(sphere.radius,sphere.radius);
    
    int result = -1; // Return value for no intersection

    if (sqrtTerm >= 0) // If there is an intersection (more likely 2)
    {
        sqrtTerm = fp_sqrt(sqrtTerm);
        // There are usually two solutions, for the two intersection points
        // between the ray and sphere.
        int solution1 = directionDotPosition + sqrtTerm;
        int solution2 = directionDotPosition - sqrtTerm;

        // We want the nearest non-negative (behind the ray origin) intersection
        if (solution1 >= 0)
        {
            result = solution1;
            if (solution2 >= 0 && solution2 < solution1)
                result = solution2;
        }
        else if (solution2 >= 0)
            result = solution2;
    }

    return result;
}
Exemple #8
0
void OWTriangle::defaulGeneralCalNorVec()
{
    OWVector4* AB = vectorSubtract(&(myVector[1]),&(myVector[0]));
    OWVector4* AC = vectorSubtract(&(myVector[2]),&(myVector[0]));
    OWVector4* tempVec = crossProduct(AB,AC);
    float tempx, tempy, tempz;
    tempx = tempVec->getX();
    tempy = tempVec->getY();
    tempz = tempVec->getZ();
    generalNorVec.setX(tempx);
    generalNorVec.setY(tempy);
    generalNorVec.setZ(tempz);
    for (int i=0; i<3; i++) {
        norVec[i].setX(tempx);
        norVec[i].setY(tempy);
        norVec[i].setZ(tempz);
    }
    delete tempVec;
    delete AB;
    delete AC;
}
Exemple #9
0
// check if one object has collided with another object
// returns true if the two objects have collided
bool checkCollision(movableObject& obj1, movableObject& obj2) {	
	vector2 diff = vectorSubtract(obj1.position, obj2.position);
	float mag = getMagnitude(diff);
	
	if(mag > 0 && mag < obj1.height){
		// collision
		obj1.speed = multiplyScalar( getNormal(diff), 5);
		obj2.speed = multiplyScalar( getNormal(diff), -5);
		return true;
	}
	return false;
}
Exemple #10
0
// Gets a sphere that completely surrounds a bounding box
_C3DTSpheroid sphereFromBounds(_C3DTBounds b)
{
    _C3DTSpheroid	s;

    // Center is the middle point between the 2 bounds coordinate
    s.center.cartesian.x = (b.topRightFar.cartesian.x + b.bottomLeftNear.cartesian.x) / 2.0f;
    s.center.cartesian.y = (b.topRightFar.cartesian.y + b.bottomLeftNear.cartesian.y) / 2.0f;
    s.center.cartesian.z = (b.topRightFar.cartesian.z + b.bottomLeftNear.cartesian.z) / 2.0f;

    s.radius = vectorLength( vectorSubtract(b.topRightFar, s.center));

    return s;
}
Exemple #11
0
int main() {
	// Create a drawing grid
	struct winsize terminal;
	ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminal);
	int		w = terminal.ws_col,
			h = terminal.ws_row - 1;

	Grid grid = gridInit(w, h);

	Vector v1 = vectorMake(20, 0, 0);
	Vector v2 = vectorMake(0, 10, 0);
	Vector center = vectorMake((int)w/2, (int)h, 0);
	Vector zero = vectorMake(0, 0, 0);

	Vector v3 = vectorSubtract(v1, v2);

	// A mechanism for delay between draws
	struct timespec t;
	t.tv_sec = 0; //1;
	t.tv_nsec = 1000 * 1000 * 100;

	// Rotation
	int		degrees = 0,
			x = 0,
			y = 0,
			z = 0;
	double	radians;
	Vector	v4;

	int test = 1;
	while (test) {
		// Calculations
		v4 = vectorRotate(v1, degrees);
		degrees += 6;
		// Erase the grid
		//grid = gridInit(w, h);

		// Draw a vector
		drawVectorAtOrigin(v4, center, grid);

		// Flush grid to the terminal
		gridDraw(grid);

		//v1.y++;

		nanosleep(&t, NULL);
	}

	return 0;
}
// Calculate the refraction when vector n1 goes from a material with refractive
// index mu1 into one with refractive index mu2, via a surface with normal s
// (s goes in the direction in to the new material, so may actually be the
// inverse of the collision-object surface normal depending on if the ray is
// entering or exiting the object)
struct Vector3 vectorRefract(struct Vector3 n1, 
                    struct Vector3 s, int mu1, int mu2)
{
    int n1DotS      = vectorUnitDotProduct(n1,s);
    struct Vector3 firstTerm   = vectorScalarMultiply(s,n1DotS);
    int sqrtTerm    = fp_sqrt(  (fp_mult(mu2,mu2)) - \
                                (fp_mult(mu1,mu1)) + \
                                (fp_mult(n1DotS,n1DotS)) );
    struct Vector3 result = \
        vectorAdd( vectorSubtract(n1, firstTerm),
            vectorScalarMultiply(s, sqrtTerm) );

    return result;  
}
Exemple #13
0
void v2c (const VECTOR3 * const vector, int * x, int * y)
{
	int
		xGrid,
		yGrid,
		i = 0;
	VECTOR3
		offset,
		centre;
	assert (x != NULL && y != NULL);
	
	xGrid = (int)(vector->x / 45.0);
	yGrid = (int)((vector->z - xGrid * 26.0) / 52.0);
	centre = hex_xyCoord2Space (xGrid, yGrid);
	offset = vectorSubtract (vector, &centre);
	if (pointInHex (&offset))
	{
		*x = xGrid;
		*y = yGrid;
		//printf ("%.2f, %.2f -> %d, %d\n", vector->x, vector->z, *x, *y);
		return;
	}
	while (i < 6)
	{
		centre = hex_xyCoord2Space (xGrid + XY[i][X], yGrid + XY[i][Y]);
		offset = vectorSubtract (vector, &centre);
		if (pointInHex (&offset))
		{
			*x = xGrid + XY[i][X];
			*y = yGrid + XY[i][Y];
			//printf ("%.2f, %.2f -> %d, %d\n", vector->x, vector->z, *x, *y);
			return;
		}
		i++;
	}
	assert (false);
}
Exemple #14
0
bool line_triHit (const LINE3 * const line, const VECTOR3 * const tri, float * tAtIntersection)
{
	VECTOR3
		u, v,
		triPlane,
		hit;
	LINE3
		transLine;
	float
		t,
		weight[3];
	u = vectorSubtract (&tri[2], &tri[0]);
	v = vectorSubtract (&tri[1], &tri[0]);
	triPlane = vectorCross (&u, &v);
	// the planeHit code doesn't have a magnitude argument so it's always a test against the plane through the origin. thus to accurately test we have to translate the line so that it's positioned relative to the plane origin (which we're arbitrarily using tri->pts[0] as) - xph 02 13 2012
	transLine.origin = vectorSubtract (&line->origin, &tri[0]);
	transLine.dir = line->dir;
	if (!line_planeHit (&transLine, &triPlane, &t))
		return false;
	hit = vectorCreate
	(
		transLine.origin.x + line->dir.x * t,
		transLine.origin.y + line->dir.y * t,
		transLine.origin.z + line->dir.z * t
	);
	baryWeights (&hit, &u, &v, weight);
	if (weight[0] >= 0.00 && weight[0] <= 1.00 &&
		weight[1] >= 0.00 && weight[1] <= 1.00 &&
		weight[2] >= 0.00 && weight[2] <= 1.00)
	{
		if (tAtIntersection)
			*tAtIntersection = t;
		return true;
	}
	return false;
}
//check if two objects have collided with one another, return true if collided
bool checkCollision(movableObject& obj1, movableObject& obj2, bool bBall)
{
	vector2 vDifference = vectorSubtract(obj1.v2Position, obj2.v2Position);
	float fMag = getMagnitude(vDifference);

	if( fMag > 0 && fMag < obj1.iHeight )
	{
		if( !bBall )
		{
			//collide
			obj1.v2Speed = multiplyScalar( getNormal(vDifference), 5 );
			obj2.v2Speed = multiplyScalar( getNormal(vDifference), -5 );
		}
		return true;
	}
	return false;
}
Exemple #16
0
void textureDrawLine (TEXTURE t, VECTOR3 start, VECTOR3 end)
{
	VECTOR3
		diff = vectorSubtract (&end, &start),
		norm = vectorNormalize (&diff),
		current = start;
	/* i'm using i/max as a counter since due to floating point rounding error
	 * it's not feasible to use vector_cmp (&current, &end), which is the only
	 * other way i can think of to check for when the line is actually done
	 *  - xph 2011 08 27
	 */
	int
		i = 0,
		max = vectorMagnitude (&diff) + 1;
	/* if start is out of bounds skip ahead until it isn't (if it isn't), and
	 * if it goes out of bounds again then it's not coming back. this is
	 * important if start is out of bounds but end isn't (or if they're both
	 * oob but they cross the image edge at some point); the start of the line
	 * won't be drawn but stopping after the first oob coordiante would be
	 * wrong
	 * (there's a better way to do this: if either value is oob, calculate the
	 * intersection of the line w/ the screen edges and jump to that point
	 * without needing to loop)
	 *  - xph 2011 08 27
	 */
	while (textureOOB (t, current) && i < max)
	{
		current = vectorAdd (&current, &norm);
		i++;
	}
	while (i < max)
	{
		if (textureOOB (t, current))
			break;
		textureDrawPixel (t, current);
		current = vectorAdd (&current, &norm);
		i++;
	}
}
Exemple #17
0
void gluLookAt(  vec3_t vEye,  vec3_t vLookat, vec3_t vUp ,matrix_t fModelView)
{
	vec3_t vN,vU,vV;
	
    // determine the new n
    vectorSubtract(vEye,vLookat,vN);
	
    // determine the new u by crossing with the up vector
    vectorCrossProduct(vUp, vN, vU) ;
	
    // normalize both the u and n vectors
    normalize(vU) ; 
	normalize(vN);
	
    // determine v by crossing n and u
    vectorCrossProduct(vN,vU,vV);
	
    // create a model view matrix
	fModelView[0] = vU[0];					fModelView[4] = vU[1];					fModelView[8] = vU[2];					fModelView[12] = - DotProduct(vEye,vU); 
	fModelView[1] = vV[0];					fModelView[5] = vV[1];					fModelView[9] = vV[2];					fModelView[13] = - DotProduct(vEye,vV);
	fModelView[2] = vN[0];					fModelView[6] = vN[1];					fModelView[10]= vN[2];					fModelView[14]=  - DotProduct(vEye,vN);
	fModelView[3]=	0.0f;					fModelView[7]= 0.0f;					fModelView[11]= 0.0f;					fModelView[15]= 1.0f;

}
Exemple #18
0
void drawTriangleToRaster(OWRaster *raster, 
                          OWTriangle& triangle, 
                          OWMaterial material, 
                          OWScene scene,
                          bool phong,
                          OWVector4* camPosition)
{
    OWColorFloat* fillcolorF = material.color;
    unsigned rasterHeight = raster->getHeight();
    unsigned rasterWidth = raster->getWidth();
    float lambda1;
    float lambda2;
    float lambda3;
    float zDepth;
    lambda1=lambda3=lambda2=0.0f;
    
    float zb1=triangle.zBuffer[0];
    float zb2=triangle.zBuffer[1];
    float zb3=triangle.zBuffer[2];
    
    float xLength = scene.maxX - scene.minX;
    float yLength = scene.maxY - scene.minY;
    
    float x1,x2,x3,y1,y2,y3,z1,z2,z3;
    x1 = triangle.getVec1().getX();
    x2 = triangle.getVec2().getX();
    x3 = triangle.getVec3().getX();
    
    y1 = triangle.getVec1().getY();
    y2 = triangle.getVec2().getY();
    y3 = triangle.getVec3().getY();
    
    z1 = triangle.getVec1().getZ();
    z2 = triangle.getVec2().getZ();
    z3 = triangle.getVec3().getZ();
    
    float maxTX=fminf(scene.maxX,fmaxf(x1, fmaxf(x2, x3)));
    float maxTY=fminf(scene.maxY,fmaxf(y1, fmaxf(y2, y3)));
    float minTX=fmaxf(scene.minX,fminf(x1, fminf(x2, x3)));
    float minTY=fmaxf(scene.minY,fminf(y1, fminf(y2, y3)));

    unsigned maxRX = ceilf(fminf(rasterWidth, (maxTX - scene.minX)/xLength*(float)rasterWidth));
    unsigned minRX = floorf(fmaxf(0.0f,       (minTX - scene.minX)/xLength*(float)rasterWidth));
    unsigned maxRY = ceilf(fminf(rasterWidth, (maxTY - scene.minY)/yLength*(float)rasterHeight));
    unsigned minRY = floorf(fmaxf(0.0f,       (minTY - scene.minY)/yLength*(float)rasterHeight));
    
    if (maxRX > rasterWidth) {
        printf("raster x max bound error.\n");
        //system("pause");
        maxRX = rasterWidth;
    }
    if (maxRY > rasterHeight) {
        printf("raster y max bound error.\n");
        //system("pause");
        maxRY = rasterHeight;
    }
    
    for (unsigned y=minRY; y<maxRY; y++) {
        for (unsigned x=minRX; x<maxRX; x++) {
            float fx=((float)x/(float)rasterWidth) * xLength+scene.minX;
            float fy=((float)y/(float)rasterHeight)* yLength+scene.minY;
            calculateTriBarycentricCoordinates(triangle, fx, fy, &lambda1, &lambda2, &lambda3);
            zDepth = zb1*lambda1 + zb2*lambda2 + zb3*lambda3;
            if(
               lambda1 >= 0.0f && lambda2 >= 0.0f && lambda3 >= 0.0f 
               //&& (lambda1 <= 0.02f || lambda2 <= 0.02f || lambda3 <= 0.02f)
               && raster->z_buffer[x + y * rasterWidth] > zDepth
               //lambda1 <= 1.0f && lambda2 <= 1.0f && lambda3 <= 1.0f
               )
            {
                raster->z_buffer[x + y * rasterWidth] = zDepth;
                OWColorChannelFloat red,green,blue;
                red = fillcolorF[0].r * lambda1 + fillcolorF[1].r * lambda2 + fillcolorF[2].r * lambda3;
                green = fillcolorF[0].g * lambda1 + fillcolorF[1].g * lambda2 + fillcolorF[2].g * lambda3;
                blue = fillcolorF[0].b * lambda1 + fillcolorF[1].b * lambda2 + fillcolorF[2].b * lambda3;
                if (phong == true) {
/***Phong Mode*************************************************************************************/
                    for (list<OWLight>::iterator iterLight = scene.lightList.begin(); iterLight != scene.lightList.end(); iterLight++) {
                        OWVector4* currVector = new OWVector4;
                        OWVector4* n = new OWVector4;
                        
                        currVector->setX(triangle.worldCoorVec[0].getX() * lambda1 + triangle.worldCoorVec[1].getX() * lambda2 + triangle.worldCoorVec[2].getX() * lambda3);
                        currVector->setY(triangle.worldCoorVec[0].getY() * lambda1 + triangle.worldCoorVec[1].getY() * lambda2 + triangle.worldCoorVec[2].getY() * lambda3);
                        currVector->setZ(triangle.worldCoorVec[0].getZ() * lambda1 + triangle.worldCoorVec[1].getZ() * lambda2 + triangle.worldCoorVec[2].getZ() * lambda3);
                        
                        for (int i=0; i<3; i++) {
                            triangle.norVec[i].normalise();
                        }
                        n->setX(triangle.norVec[0].getX() * lambda1 + triangle.norVec[1].getX() * lambda2 + triangle.norVec[2].getX() * lambda3);
                        n->setY(triangle.norVec[0].getY() * lambda1 + triangle.norVec[1].getY() * lambda2 + triangle.norVec[2].getY() * lambda3);
                        n->setZ(triangle.norVec[0].getZ() * lambda1 + triangle.norVec[1].getZ() * lambda2 + triangle.norVec[2].getZ() * lambda3);
                        
                        OWVector4* l = vectorSubtract((*iterLight).myPosition, currVector);
                        
                        l->normalise();
                        n->normalise();
                        float l_dot_n = l->dotProduct(*n);
                        float diffContr = fmaxf(0.0f, l_dot_n);
                        
                        n->scale(2*l_dot_n);
                        OWVector4* r = vectorSubtract(n,l);
                        OWVector4* v = vectorSubtract(camPosition, currVector);
                        r->normalise();
                        v->normalise();
                        
                        OWColorFloat Idif;
                        if (diffContr < 0.0f) {
                            diffContr = 0.0f;
                        }
                        Idif.a=1.0f;
                        Idif.r=(*iterLight).myColor.r * red * diffContr;
                        Idif.g=(*iterLight).myColor.g * green * diffContr;
                        Idif.b=(*iterLight).myColor.b * blue * diffContr;
                        
                        OWColorFloat shininessColor = material.shininessColor;
                        OWColorFloat Ispec;
                        float specContri = powf(v->dotProduct(*r), shininessColor.a);
                        //float specContri = v->dotProduct(*r);
                        if (
                            l_dot_n >= 0.0f 
                            && specContri >= 0.0f
                            ) {
                            Ispec.a = 1.0f;
                            Ispec.r = (*iterLight).myColor.r * shininessColor.r * specContri;
                            Ispec.g = (*iterLight).myColor.g * shininessColor.g * specContri;
                            Ispec.b = (*iterLight).myColor.b * shininessColor.b * specContri;
                        }else{
                            Ispec.a = 0.0f;
                            Ispec.r = 0.0f;
                            Ispec.g = 0.0f;
                            Ispec.b = 0.0f;
                        }
                        scene.ambient.a = 0.0f;
                        //OWColorFloat tempColor = Idif;
                        //OWColorFloat tempColor = Ispec;
                        //OWColorFloat tempColor = scene.ambient;
                        //OWColorFloat tempColor = colorAdd(Idif, scene.ambient);
                        //OWColorFloat tempColor = colorAdd(Idif, Ispec);
                        OWColorFloat tempColor = colorAdd(Idif, colorAdd(Ispec, scene.ambient));
                        
                        colorNormalise(tempColor);
                        
                        red = tempColor.r;
                        green = tempColor.g;
                        blue = tempColor.b;
                    }
                    
                }
               
                raster->pixels[x + y * rasterWidth] = drawARGBColorFromFloatColor(red, green, blue);
            }
        }
    }
    //triangle.printMyself();
    
}
Exemple #19
0
void MD5_GenerateLightingInfo (md5_mesh_t* mesh)
{
	int verticesCounter;
	int weightCounter;
	//User for tangent space generation
	vec3_t v1,v2,normal;
	
	vec3_t* normalAccumulator;
	vec3_t* normalWeightAccumulator;

	vec3_t tangent;
	float coef;
	vec3_t jointSpaceTangent;
	vec2_t st1,st2;
	vec3_t* tangentAccumulator;
	vec3_t* tangentWeightAccumulator;

	
	vertex_t* currentVertex = NULL;
	md5_vertex_t* md5Vertex;
	int facesCounter;
	
	md5_weight_t* weight;
	md5_bone_t* bone;
	md5_triangle_t* currentFace;
	
	vec3_t jointSpaceNormal;
	
	normalAccumulator		=	calloc(mesh->numVertices, sizeof(vec3_t));
	normalWeightAccumulator =	calloc(mesh->numWeights, sizeof(vec3_t));

	tangentAccumulator		=	calloc(mesh->numVertices, sizeof(vec3_t));
	tangentWeightAccumulator=	calloc(mesh->numWeights, sizeof(vec3_t));

	
	//printf("\nGenerating normal and tangents.\n");

	
	//Generate the normal and tangent per face
	currentFace = mesh->triangles;
	for(facesCounter = 0; facesCounter < mesh->numTriangles ; facesCounter++,currentFace++)
	{
		
		// Normal part
		vectorSubtract(mesh->vertexArray[currentFace->index[2]].pos , mesh->vertexArray[currentFace->index[0]].pos, v1);
		vectorSubtract(mesh->vertexArray[currentFace->index[1]].pos , mesh->vertexArray[currentFace->index[0]].pos, v2);
		vectorCrossProduct(v2,v1,normal);
		
		normalize(normal);
		
		vectorAdd(normalAccumulator[currentFace->index[0]],normal,normalAccumulator[currentFace->index[0]]);
		vectorAdd(normalAccumulator[currentFace->index[1]],normal,normalAccumulator[currentFace->index[1]]);
		vectorAdd(normalAccumulator[currentFace->index[2]],normal,normalAccumulator[currentFace->index[2]]);
		
		
		// The following part is from "Mathematic for 3D programming" by Eric Lengyel
		// Tangent part
		


		vector2Subtract(mesh->vertexArray[currentFace->index[2]].text,mesh->vertexArray[currentFace->index[0]].text,st1);
		vector2Subtract(mesh->vertexArray[currentFace->index[1]].text,mesh->vertexArray[currentFace->index[0]].text,st2);
		
		vector2Scale(st1,1/(float)32767,st1);
		vector2Scale(st2,1/(float)32767,st2);
		
		if (st1[0] == 0.0f && st2[0] == 0.0f)
		{
			st1[0] = 0.1f ; 
			st2[0] = 0.1f;
		}
		
		if (st1[1] == 0.0f && st2[1] == 0.0f)
		{
			st1[1] = 0.1f ;
			st2[1] = 0.1f;
		}
		
		
		coef = 1/ (st1[0] * st2[1] - st2[0] * st1[1]);
		
		
		
		tangent[0] = coef * (v1[0] * st2[1]  + v2[0] * -st1[1]);
		tangent[1] = coef * (v1[1] * st2[1]  + v2[1] * -st1[1]);
		tangent[2] = coef * (v1[2] * st2[1]  + v2[2] * -st1[1]);
		
		normalize(tangent);		
		
		
		vectorAdd(tangentAccumulator[currentFace->index[0]],tangent,tangentAccumulator[currentFace->index[0]]);
		vectorAdd(tangentAccumulator[currentFace->index[1]],tangent,tangentAccumulator[currentFace->index[1]]);
		vectorAdd(tangentAccumulator[currentFace->index[2]],tangent,tangentAccumulator[currentFace->index[2]]);
		
		
		
	}
	
	//Normalize accumulated normal and tangent
	for(verticesCounter=0 ; verticesCounter < mesh->numVertices ; verticesCounter++,currentVertex++)
	{
		
		
		normalize(normalAccumulator[verticesCounter]);
//		printf("normalized accumulated normal [%d][%.2f,%.2f,%.2f]\n",verticesCounter,normalAccumulator[verticesCounter][0],normalAccumulator[verticesCounter][1],normalAccumulator[verticesCounter][2]);
		normalize(tangentAccumulator[verticesCounter]);
//		printf("normalized accumulated tangent [%d][%.2f,%.2f,%.2f]\n",verticesCounter,tangentAccumulator[verticesCounter][0],tangentAccumulator[verticesCounter][1],tangentAccumulator[verticesCounter][2]);
	}
	
	//Now we have all the normal for this model, but need to transform them in bone space for re-usage
	// Translating the normal orientation from object to joint space and Store normals inside weights, 
	md5Vertex = mesh->vertices;
	currentVertex = mesh->vertexArray;
	for(verticesCounter=0 ; verticesCounter < mesh->numVertices ; verticesCounter++,md5Vertex++)
	{
		for (weightCounter = 0; weightCounter < md5Vertex->count; weightCounter++)
		{
			weight = &mesh->weights[md5Vertex->start + weightCounter];
			bone  = &mesh->bones[weight->boneId];
			
			multiplyByInvertQuaternion(normalAccumulator[verticesCounter],bone->orientation,jointSpaceNormal);
			vectorAdd(normalWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceNormal,normalWeightAccumulator[md5Vertex->start + weightCounter]);
					
			multiplyByInvertQuaternion(tangentAccumulator[verticesCounter],bone->orientation,jointSpaceTangent);
			vectorAdd(tangentWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceTangent,tangentWeightAccumulator[md5Vertex->start + weightCounter]);			
		}
		
	}
	
	weight = mesh->weights;
	for (weightCounter = 0; weightCounter < mesh->numWeights; weightCounter++,weight++)
	{
		normalize(normalWeightAccumulator[weightCounter]);
		vectorScale(normalWeightAccumulator[weightCounter],32767,weight->boneSpaceNormal);
		
		normalize(tangentWeightAccumulator[weightCounter]);
		vectorScale(tangentWeightAccumulator[weightCounter],32767,weight->boneSpaceTangent);
			
	}
	
	free(normalAccumulator);
	free(normalWeightAccumulator);

	free(tangentAccumulator);
	free(tangentWeightAccumulator);

}
Exemple #20
0
void Lines::update()
{
  //Skip update if count hasn't changed
  //To force update, set geometry->reload = true
  if (reload) elements = 0;
  if (elements > 0 && (linetotal == (unsigned int)elements || total == 0)) return;

  tris->clear();
  tris->setView(view);

  //Count 2d lines
  linetotal = 0;
  for (unsigned int i=0; i<geom.size(); i++)
  { //Force true as default here, global default is false for "flat"
    if (all2d || (geom[i]->draw->properties.getBool("flat", true) && !geom[i]->draw->properties["tubes"]))
      linetotal += geom[i]->count;
  }

  //Copy data to Vertex Buffer Object
  // VBO - copy normals/colours/positions to buffer object
  unsigned char *p, *ptr;
  ptr = p = NULL;
  int datasize = sizeof(float) * 3 + sizeof(Colour);   //Vertex(3), and 32-bit colour
  int bsize = linetotal * datasize;
  if (linetotal > 0)
  {
    //Initialise vertex buffer
    if (!vbo) glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    if (glIsBuffer(vbo))
    {
      glBufferData(GL_ARRAY_BUFFER, bsize, NULL, GL_STATIC_DRAW);
      debug_print("  %d byte VBO created for LINES, holds %d vertices\n", bsize, bsize/datasize);
      ptr = p = (unsigned char*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
      GL_Error_Check;
    }
    if (!p) abort_program("VBO setup failed");
  }

  clock_t t1,t2,tt;
  tt=clock();
  counts.clear();
  counts.resize(geom.size());
  any3d = false;
  for (unsigned int i=0; i<geom.size(); i++)
  {
    t1=tt=clock();
    Properties& props = geom[i]->draw->properties;

    //Calibrate colour maps on range for this object
    geom[i]->colourCalibrate();
    float limit = props["limit"];
    bool linked = props["link"];

    if (all2d || (props.getBool("flat", true) && !props["tubes"]))
    {
      int hasColours = geom[i]->colourCount();
      int colrange = hasColours ? geom[i]->count / hasColours : 1;
      if (colrange < 1) colrange = 1;
      debug_print("Using 1 colour per %d vertices (%d : %d)\n", colrange, geom[i]->count, hasColours);

      Colour colour;
      for (unsigned int v=0; v < geom[i]->count; v++)
      {
        if (!internal && geom[i]->filter(i)) continue;

        //Check length limit if applied (used for periodic boundary conditions)
        //NOTE: will not work with linked lines, require separated segments
        if (!linked && v%2 == 0 && v < geom[i]->count-1 && limit > 0.f)
        {
          Vec3d line;
          vectorSubtract(line, geom[i]->vertices[v+1], geom[i]->vertices[v]);
          if (line.magnitude() > limit) 
          {
            //Skip next two vertices
            v++;
            continue;
          }
        }

        //Have colour values but not enough for per-vertex, spread over range (eg: per segment)
        int cidx = v / colrange;
        if (cidx >= hasColours) cidx = hasColours - 1;
        geom[i]->getColour(colour, cidx);
        //if (cidx%100 ==0) printf("COLOUR %d => %d,%d,%d\n", cidx, colour.r, colour.g, colour.b);
        //Write vertex data to vbo
        assert((int)(ptr-p) < bsize);
        //Copies vertex bytes
        memcpy(ptr, &geom[i]->vertices[v][0], sizeof(float) * 3);
        ptr += sizeof(float) * 3;
        //Copies colour bytes
        memcpy(ptr, &colour, sizeof(Colour));
        ptr += sizeof(Colour);

        //Count of vertices actually plotted
        counts[i]++;
      }
      t2 = clock();
      debug_print("  %.4lf seconds to reload %d vertices\n", (t2-t1)/(double)CLOCKS_PER_SEC, counts[i]);
      t1 = clock();
      elements += counts[i];
    }
    else
    {
      any3d = true; //Flag 3d tubes drawn

      //Create a new data store for output geometry
      tris->add(geom[i]->draw);

      //3d lines - using triangle sub-renderer
      geom[i]->draw->properties.data["lit"] = true; //Override lit
      //Draw as 3d cylinder sections
      int quality = 4 * (int)props["glyphs"];
      float scaling = props["scalelines"];
      //Don't apply object scaling to internal lines objects
      if (!internal) scaling *= (float)props["scaling"];
      float radius = scaling*0.1;
      float* oldpos = NULL;
      Colour colour;
      for (unsigned int v=0; v < geom[i]->count; v++)
      {
        if (v%2 == 0 && !linked) oldpos = NULL;
        float* pos = geom[i]->vertices[v];
        if (oldpos)
        {
          tris->drawTrajectory(geom[i]->draw, oldpos, pos, radius, radius, -1, view->scale, limit, quality);
          //Per line colours (can do this as long as sub-renderer always outputs same tri count)
          geom[i]->getColour(colour, v);
          tris->read(geom[i]->draw, 1, lucRGBAData, &colour.value);
        }
        oldpos = pos;
      }

      //Adjust bounding box
      tris->compareMinMax(geom[i]->min, geom[i]->max);
    }
  }

  if (linetotal > 0)
  {
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
  }
  GL_Error_Check;

  t1 = clock();
  debug_print("Plotted %d lines in %.4lf seconds\n", linetotal, (t1-tt)/(double)CLOCKS_PER_SEC);

  tris->update();
}
Exemple #21
0
void GenerateLightingInfo (const md5_mesh_t *mesh, md5_joint_t *skeleton)
{

	int verticesCounter;
	int weightCounter;
	//User for tangent space generation
	vec3_t v1,v2,normal;
	
	vec3_t* normalAccumulator;
	vec3_t* normalWeightAccumulator;
	#ifdef TANGENT_ENABLED
	vec3_t tangent;
	float coef;
	vec3_t jointSpaceTangent;
	vec2_t st1,st2;
	vec3_t* tangentAccumulator;
	vec3_t* tangentWeightAccumulator;
	#endif
	
	vertex_t* currentVertex = NULL;
	md5_vertex_t* md5Vertex;
	int facesCounter;
	
	md5_weight_t* weight;
	md5_joint_t* joint;
	md5_triangle_t* currentFace;
	
	vec3_t jointSpaceNormal;
	
	normalAccumulator = calloc(mesh->num_verts, sizeof(vec3_t));
	normalWeightAccumulator = calloc(mesh->num_weights, sizeof(vec3_t));
 	#ifdef TANGENT_ENABLED
	tangentAccumulator = calloc(mesh->num_verts, sizeof(vec3_t));
	tangentWeightAccumulator  = calloc(mesh->num_weights, sizeof(vec3_t));
	#endif
	
	//Set all textures coordinate once for all.
	currentVertex = mesh->vertexArray;
	for(verticesCounter=0 ; verticesCounter < mesh->num_verts ; verticesCounter++,currentVertex++)
	{
		currentVertex->text[0] = mesh->vertices[verticesCounter].st[0];
		currentVertex->text[1] = mesh->vertices[verticesCounter].st[1];
	}
	
	currentFace = mesh->triangles;
	for(facesCounter = 0; facesCounter < mesh->num_tris ; facesCounter++,currentFace++)
	{
		
		// Normal part
		vectorSubtract(mesh->vertexArray[currentFace->index[2]].pos , mesh->vertexArray[currentFace->index[0]].pos, v1);
		vectorSubtract(mesh->vertexArray[currentFace->index[1]].pos , mesh->vertexArray[currentFace->index[0]].pos, v2);
		vectorCrossProduct(v2,v1,normal);
		
		vectorAdd(normalAccumulator[currentFace->index[0]],normal,normalAccumulator[currentFace->index[0]]);
		vectorAdd(normalAccumulator[currentFace->index[1]],normal,normalAccumulator[currentFace->index[1]]);
		vectorAdd(normalAccumulator[currentFace->index[2]],normal,normalAccumulator[currentFace->index[2]]);
		
		
		// The following part is from "Mathematic for 3D programming" by Eric Lengyel
		// Tangent part
		#ifdef TANGENT_ENABLED
		vector2Subtract(mesh->vertexArray[currentFace->index[2]].text,mesh->vertexArray[currentFace->index[0]].text,st1);
		vector2Subtract(mesh->vertexArray[currentFace->index[1]].text,mesh->vertexArray[currentFace->index[0]].text,st2);
		
		coef = 1/ (st1[0] * st2[1] - st2[0] * st1[1]);
		
		tangent[0] = coef * (v1[0] * st2[1]  + v2[0] * -st1[1]);
		tangent[1] = coef * (v1[1] * st2[1]  + v2[1] * -st1[1]);
		tangent[2] = coef * (v1[2] * st2[1]  + v2[2] * -st1[1]);
		
		vectorAdd(tangentAccumulator[currentFace->index[0]],tangent,tangentAccumulator[currentFace->index[0]]);
		vectorAdd(tangentAccumulator[currentFace->index[1]],tangent,tangentAccumulator[currentFace->index[1]]);
		vectorAdd(tangentAccumulator[currentFace->index[2]],tangent,tangentAccumulator[currentFace->index[2]]);
						
		#endif
	}
	
	
	for(verticesCounter=0 ; verticesCounter < mesh->num_verts ; verticesCounter++,currentVertex++)
	{
		normalize(normalAccumulator[verticesCounter]);
		#ifdef TANGENT_ENABLED			
		normalize(tangentAccumulator[verticesCounter]);
		#endif
	}
	
	//Now we have all the normal for this model, but need to transform them in bone space for re-usage
	// Translating the normal orientation from object to joint space and Store normals inside weights, 
	md5Vertex = mesh->vertices;
	currentVertex = mesh->vertexArray;
	for(verticesCounter=0 ; verticesCounter < mesh->num_verts ; verticesCounter++,md5Vertex++)
	{
		for (weightCounter = 0; weightCounter < md5Vertex->count; weightCounter++)
		{
			weight = &mesh->weights[md5Vertex->start + weightCounter];
			joint  = &skeleton[weight->joint];
			
			multiplyByInvertQuaternion(normalAccumulator[verticesCounter],joint->orient,jointSpaceNormal);
			vectorAdd(normalWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceNormal,normalWeightAccumulator[md5Vertex->start + weightCounter]);
						
			#ifdef TANGENT_ENABLED			
			multiplyByInvertQuaternion(tangentAccumulator[verticesCounter],joint->orient,jointSpaceTangent);
			vectorAdd(tangentWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceTangent,tangentWeightAccumulator[md5Vertex->start + weightCounter]);
			#endif
						
		}
		
	}
	
	weight = mesh->weights;
	for (weightCounter = 0; weightCounter < mesh->num_weights; weightCounter++,weight++)
	{
		normalize(normalWeightAccumulator[weightCounter]);
		vectorScale(normalWeightAccumulator[weightCounter],32767,weight->normal);
		#ifdef TANGENT_ENABLED			
			normalize(tangentWeightAccumulator[weightCounter]);
		vectorScale(tangentWeightAccumulator[weightCounter],32767,weight->tangent);
		#endif			
	}
	
	free(normalAccumulator);
	free(normalWeightAccumulator);
	#ifdef TANGENT_ENABLED	
	free(tangentAccumulator);
	free(tangentWeightAccumulator);
	#endif	
}
Exemple #22
0
// Returns (b-a) x (c-a)
inline C3DTVector vectorCrossProductTri(const C3DTVector a, const C3DTVector b, const C3DTVector c) {

	return vectorCrossProduct(vectorSubtract(b,a), vectorSubtract(c,a));
}
Exemple #23
0
// calculate height at (x,y) with plane
float Terrain::getHeight (float x_float, float z_float, Angle &a) {
    Vector v1, v2, v3, normal, ab, bc;
    Plane plane;
    bool up;
    int res_int = (int) res;
    int x = (int) (x_float);
    int z = (int) (z_float);
    int xs, zs;
    xs = (int) ((x+size/2) / res_int) * res_int - (size/2);
    zs = (int) ((z+size/2) / res_int) * res_int - (size/2);
    // FIND PLANE EQUATION (Ax + By + Cz + D)
    // find triangle - START
    // mi servono i vertici della diagonale -> 0 e 2
    v1.x = xs;
    v1.z = zs;
    v1.y = getHeightFromMap (v1.x+size/2, v1.z+size/2);
    v3.x = xs + res;
    v3.z = zs + res;
    v3.y = getHeightFromMap (v3.x+size/2, v3.z+size/2);
    // calcolo la retta passante per i punti
    float rect_z = v3.z * ((xs-v1.x)/(v3.x-v1.x));
    if (z_float > rect_z)
        up = true;
    else
        up = false;

    // find triangle - END
    if (up) {
        v2.x = xs;
        v2.z = zs + res;
        v2.y = getHeightFromMap (v2.x+size/2, v2.z+size/2);
    }
    else {
        v2.x = xs + res;
        v2.z = zs;
        v2.y = getHeightFromMap (v2.x+size/2, v2.z+size/2);
    }
    // calculate plane equation
    vectorSubtract (v1, v2, ab);
    vectorSubtract (v2, v3, bc);
    crossProduct (ab, bc, normal);
    makePlane (v1, normal, plane);

    // calculate height
    float height = (plane.d - (plane.a * x_float) - (plane.c * z_float)) / plane.b;

    // calculate angle x
    Vector temp_vec;
    temp_vec.x = 1.0;
    temp_vec.y = 0.0;
    temp_vec.z = 0.0;
    float temp_angle_x = vectorAngle (temp_vec, normal);
    a.x = 90.0 - temp_angle_x;
    // calculate angle z
    temp_vec.x = 0.0;
    temp_vec.y = 0.0;
    temp_vec.z = 1.0;
    float temp_angle_z = vectorAngle (temp_vec, normal);
    a.z = 90.0 - temp_angle_z;

    // return height
    return height;
}