Ejemplo n.º 1
0
Mapping *
SphereMappingCreate(
        Vector          *center,
        Vector          *norm,
        Vector          *uaxis)
{
	Mapping *res;

	res = (Mapping *)Malloc(sizeof(Mapping));
	res->flags = OBJSPACE;
	res->method = SphereMapping;
	if (center)
		res->center = *center;
	else
		res->center.x = res->center.y = res->center.z = 0.;
	if (norm && uaxis) {
		res->norm = *norm;
		if (VecNormalize(&res->norm) == 0.) {
			RLerror(RL_ABORT, "Degenerate mapping vector.\n");
			return (Mapping *)NULL;
		}
		if (VecNormCross(norm, uaxis, &res->vaxis) == 0.) {
			RLerror(RL_ABORT, "Degenerate mapping vector.\n");
			return (Mapping *)NULL;
		}
		(void)VecNormCross(&res->vaxis, norm, &res->uaxis);
	} else {
		res->norm.x = res->norm.y = res->uaxis.y = res->uaxis.z =
			res->vaxis.x = res->vaxis.z = 0.;
		res->norm.z = res->uaxis.x = res->vaxis.y = 1.;
	}
	return res;
}
Ejemplo n.º 2
0
void OpenGLDrawCone(VECTOR *size, ULONG flags)
{
	VECTOR bottom,bottom1, centertop;
	int i;
	VECTOR norm, e0,e1;

	if(!(flags & OBJECT_OPENBOTTOM))
	{
		glEnable(GL_CULL_FACE);
		glBegin(GL_TRIANGLE_FAN);
		glNormal3f(0.f, -1.f, 0.f);
		glVertex3f(0.f, 0.f, 0.f);

		for(i = 0; i <= 360; i += OGL_CONE_DIVS)
			glVertex3f(sin(i*PI_180)*size->x, 0.f, cos(i*PI_180)*size->z);

		glEnd();
	}

	glBegin(GL_TRIANGLE_FAN);
	glNormal3f(0.f, 1.f, 0.f);
	SetVector(&centertop, 0.f, size->y, 0.f);
	glVertex3fv((GLfloat*)&centertop);

	SetVector(&bottom, 0.f, 0.f, size->z);
	SetVector(&bottom1, sin((360-OGL_CONE_DIVS)*PI_180)*size->x, 0.f, cos((360-OGL_CONE_DIVS)*PI_180)*size->z);
	VecSub(&centertop, &bottom, &e0);
	VecSub(&centertop, &bottom1, &e1);
	VecNormCross(&e0, &e1, &norm);
	glNormal3fv((GLfloat*)&norm);
	glVertex3fv((GLfloat*)&bottom);

	for(i = 360-OGL_CONE_DIVS; i >= -OGL_CONE_DIVS; i -= OGL_CONE_DIVS)
	{
		bottom = bottom1;
		SetVector(&bottom1, sin(i*PI_180)*size->x, 0.f, cos(i*PI_180)*size->z);
		VecSub(&centertop, &bottom, &e0);
		VecSub(&centertop, &bottom1, &e1);
		VecNormCross(&e0, &e1, &norm);
		glNormal3fv((GLfloat*)&norm);
		glVertex3fv((GLfloat*)&bottom);
	}

	glEnd();

	if(!(flags & OBJECT_OPENBOTTOM))
		glDisable(GL_CULL_FACE);
}
Ejemplo n.º 3
0
/*************
 * DESCRIPTION:   Initialize Camera (MUST be called if parameters changed)
 * INPUT:         none
 * OUTPUT:        none
 *************/
void CAMERA::InitCamera()
{
	float lookdist, magnitude;
	VECTOR dir;

	VecSub(&lookp, &pos, &dir);
	firstray = dir;

	lookdist = VecNormalize(&dir);
	VecNormCross(&dir, &vup, &scrni);
	VecNormCross(&scrni, &dir, &scrnj);

	magnitude = -2.f*lookdist * (float)tan(0.5f*hfov*PI_180)/xres;

	VecScale(magnitude, &scrni, &scrnx);
	magnitude = 2.f*lookdist * (float)tan(0.5f*vfov*PI_180)/yres;

	VecScale(magnitude, &scrnj, &scrny);

	firstray.x -= 0.5f*yres*scrny.x + 0.5f*xres*scrnx.x;
	firstray.y -= 0.5f*yres*scrny.y + 0.5f*xres*scrnx.y;
	firstray.z -= 0.5f*yres*scrny.z + 0.5f*xres*scrnx.z;

	DoFData.xres = xres;
	DoFData.yres = yres;
	DoFData.left = left;
	DoFData.top = top;
	DoFData.right = right;
	DoFData.bottom = bottom;
	DoFData.focaldist = focaldist;
	DoFData.hfov = hfov*PI/180.0f;
	DoFData.vfov = vfov*PI/180.0f;
	DoFData.aperture = 2*aperture;
	DoFData.samples = 7;

	DoFData.flags = 0;
	if ((flags & HIDDENAREA) == HIDDENAREA)
		DoFData.flags = DoFHidden;
	if ((flags & ACCELERATE) == ACCELERATE)
		DoFData.flags |= DoFAccelerate;

	DoF.Init(&DoFData);
}
Ejemplo n.º 4
0
/*************
 * DESCRIPTION:   Given a vector, find two additional vectors such that all three
 *                are mutually perpendicular and uaxis X vaxis = vector.  The given
 *                vector need not be normalized. uaxis and vaxis are normalized.
 * INPUT:         vector         vector to find two vectors for
 *                uaxis          first found vector
 *                vaxis          second found vector
 * OUTPUT:        none
 *************/
void VecCoordSys(VECTOR *vector, VECTOR *uaxis, VECTOR *vaxis)
{
    uaxis->x = -vector->y;
    uaxis->y = vector->x;
    uaxis->z = 0.f;
    if (VecNormalize(uaxis) == 0.f)
    {
        uaxis->x = vector->z;
        uaxis->y = 0.f;
        uaxis->z = -vector->x;
        if (VecNormalize(uaxis) == 0.f)
            // Degenerate vector
            return;
    }
    VecNormCross(vector, uaxis, vaxis);
}
Ejemplo n.º 5
0
void
CylinderMapping(
            Mapping             *map,
            Geom                * /*obj*/,
            Vector              *pos,
            Vector              * /*norm*/,
            Vec2d               *uv,
            Vector              *dpdu,
            Vector              *dpdv)
{
	Vector vtmp;
	Float nx, ny, r;

	VecSub(*pos, map->center, &vtmp);
	nx = dotp(&map->uaxis, &vtmp);
	ny = dotp(&map->vaxis, &vtmp);
	uv->v = dotp(&map->norm, &vtmp);

	r = sqrt(nx*nx + ny*ny);

	if (r < EPSILON) {
		uv->u = 0.;
		return;
	}

	nx /= r;
	ny /= r;

	if (fabs(nx) > 1.)
		uv->u = 0.5;
	else
		uv->u = acos(nx) / TWOPI;
	if (ny < 0.)
		uv->u = 1. - uv->u;

	if (dpdv)
		*dpdv = map->norm;
	if (dpdu)
		(void)VecNormCross(&map->norm, pos, dpdu);
}
Ejemplo n.º 6
0
void OpenGLDrawMesh(TRIANGLE *trias, EDGE *edges, VECTOR *points, VECTOR *normals, ULONG acttrias)
{
	USHORT p1,p2,p3;
	ULONG i;
#ifndef NORMAL
	VECTOR e1,e2,n;
#endif // NORMAL

	glBegin(GL_TRIANGLES);
	for(i=0; i<acttrias; i++)
	{
		p1 = edges[trias->e[0]].p[0];
		p2 = edges[trias->e[0]].p[1];
		if((p1 != edges[trias->e[1]].p[0]) && (p2 != edges[trias->e[1]].p[0]))
			p3 = edges[trias->e[1]].p[0];
		else
			p3 = edges[trias->e[1]].p[1];

#ifdef NORMAL
		glNormal3fv((GLfloat*)&normals[trias->n[0]]);
		glVertex3fv((GLfloat*)&points[p1]);
		glNormal3fv((GLfloat*)&normals[trias->n[1]]);
		glVertex3fv((GLfloat*)&points[p2]);
		glNormal3fv((GLfloat*)&normals[trias->n[2]]);
		glVertex3fv((GLfloat*)&points[p3]);
#else // NORMAL
		VecSub(&points[p3], &points[p1], &e1);
		VecSub(&points[p3], &points[p2], &e2);
		VecNormCross(&e2, &e1, &n);
		glNormal3fv((GLfloat*)&n);
		glVertex3fv((GLfloat*)&points[p1]);
		glVertex3fv((GLfloat*)&points[p2]);
		glVertex3fv((GLfloat*)&points[p3]);
#endif // NORMAL
		trias++;
	}
	glEnd();
}
Ejemplo n.º 7
0
/*************
 * DESCRIPTION: read faces of object
 * INPUT:       pointer to chunk
 * OUTPUT:      -
 *************/
static void ParseFaces(HANDLER_DATA *data, CHUNK *mainchunk)
{
	CHUNK    chunk;
	UWORD    i, matcount, index, p1, p2, p3;
	VECTOR   e1, e2;
	SURFACE  *s;
	TRILIST  *hp;
	char     buf[80];

	ReadWord(data, (WORD *)&data->facecount, 1); // read number of faces

	if (data->facecount == 0)
		return;

	data->face = new FACE3DS[data->facecount];
	if (!data->face)
	{
		data->err = ERR_MEM;
		return;
	}
	if (!data->replacesurface)
	{
		data->material = (SURFACE **)malloc(sizeof(SURFACE *)*data->facecount);
		if (!data->material)
		{
			data->err = ERR_MEM;
			return;
		}
	}

	ReadWord(data, (WORD *)data->face, 4*data->facecount);   // read faces

	if (data->link->type == LINK_RENDERER)
	{
		// do it for renderer only

		data->VertNorms = new VECTOR[data->pointcount];
		if (!data->VertNorms)
		{
			data->err = ERR_MEM;
			return;
		}

		data->TriNorms = new VECTOR[data->facecount];
		if (!data->TriNorms)
		{
			data->err = ERR_MEM;
			return;
		}
		memset(data->VertNorms, 0, sizeof(VECTOR)*data->pointcount);   // Init normals

		data->TriSmooth = new UBYTE[data->facecount];
		if (!data->TriSmooth)
		{
			data->err = ERR_MEM;
			return;
		}

		for (i = 0; i < data->facecount; i++)
		{
			if (data->replacesurface)
				data->material[i] = data->replacesurface;
			else
				data->material[i] = NULL;

			data->TriSmooth[i] = FALSE;
			// get three points for the triangle
			p1 = data->face[i].p1;
			p2 = data->face[i].p3;
			p3 = data->face[i].p2;

			hp = new TRILIST;
			if (!hp)
			{
				data->err = ERR_MEM;
				return;
			}
			hp->next = data->TriList[p1];
			hp->tri = i;
			hp->flag = FALSE;
			data->TriList[p1] = hp;

			hp = new TRILIST;
			if (!hp)
			{
				data->err = ERR_MEM;
				return;
			}
			hp->next = data->TriList[p2];
			hp->tri = i;
			hp->flag = FALSE;
			data->TriList[p2] = hp;

			hp = new TRILIST;
			if (!hp)
			{
				data->err = ERR_MEM;
				return;
			}
			hp->next = data->TriList[p3];
			hp->tri = i;
			hp->flag = FALSE;
			data->TriList[p3] = hp;

			// calculate normal of triangle
			VecSub(&data->points[p3], &data->points[p1], &e1);
			VecSub(&data->points[p2], &data->points[p1], &e2);
			VecNormCross(&e1, &e2, &data->TriNorms[i]);
		}
	}
	do
	{
		BeginChunk(data, &chunk);
		switch (chunk.id)
		{
			case ID_MSHMATGROUP:
					if (!data->replacesurface)
					{
						ReadASCIIZ(data, buf);
						s = data->link->SurfaceGetByName(data->rc, buf);
						ReadWord(data, (WORD*)&matcount, 1);
						for (i = 0; i < matcount; i++)
						{
							ReadWord(data, (WORD*)&index, 1);
							data->material[index] = s;
						}
					}
					break;
			case ID_SMOOTHGROUP: // no info about this group
					break;
		}
		EndChunk(data, &chunk);
	}
	while (INCHUNK);
}
Ejemplo n.º 8
0
/*************
 * DESCRIPTION:   add a mesh and calculate normals
 * INPUT:         srf         surface
 *                surfaces    array of surface pointer, if the mesh has different surfaces (NULL else)
 *                actor       actor
 *                points      mesh points
 *                edges       mesh edges
 *                edgecount   amount of edges
 *                mesh        mesh triangles
 *                triacount   amount of triangles
 *                matrix      transform matrix
 *                rotmatrix   rotate matrix
 *                nophong     disable phong shading
 *                brushcoords brush mapping coordinates
 * OUTPUT:        first created triangle or NULL if failed
 *************/
TRIANGLE *CreateMesh(RSICONTEXT *rc, SURFACE *srf, SURFACE **surfs, ACTOR *actor, VECTOR *points, EDGE *edges, int edgecount,
	MESH *mesh, int triacount, MATRIX *matrix, MATRIX *rotmatrix, BOOL nophong, VECT2D *brushcoords)
{
	int i;
	UWORD p1,p2,p3;
	UWORD *tmpedges, *te;
	VECTOR *tmpnorms, e1,e2;
	MESH *tria;
	TRIANGLE *triangle, *t;

	if(!nophong)
	{
		tmpnorms = new VECTOR[triacount];
		if (!tmpnorms)
			return NULL;

		tmpedges = new UWORD[edgecount*2];
		if (!tmpedges)
		{
			delete tmpnorms;
			return NULL;
		}

		memset(tmpedges, 0xFF, edgecount*sizeof(UWORD)*2);

		// calculate geometric normals
		// and generate edge index
		tria = mesh;
		for (i=0; i<triacount; i++)
		{
			// calculate normals of triangles
			p1 = edges[tria->e[0]].p[0];
			p2 = edges[tria->e[0]].p[1];
			if((p1 != edges[tria->e[1]].p[0]) &&
				(p2 != edges[tria->e[1]].p[0]))
			{
				p3 = edges[tria->e[1]].p[0];
			}
			else
			{
				p3 = edges[tria->e[1]].p[1];
			}

			VecSub(&points[p2], &points[p1], &e1);
			VecSub(&points[p3], &points[p1], &e2);
			VecNormCross(&e1, &e2, &tmpnorms[i]);

			te = &tmpedges[tria->e[0]*2];
			if(te[0] == 0xFFFF)
				te[0] = i;
			else
				te[1] = i;

			te = &tmpedges[tria->e[1]*2];
			if(te[0] == 0xFFFF)
				te[0] = i;
			else
				te[1] = i;

			te = &tmpedges[tria->e[2]*2];
			if(te[0] == 0xFFFF)
				te[0] = i;
			else
				te[1] = i;

			tria++;
		}
	}

#ifndef __STORM__
	// there is a bug in StormC which causes a crash if an array
	// is allocated when the destructor of the base class is virtual.
	// I have to test again if it works when a new version is available.
	// Do also change TriangleGetNext().
	triangle = new TRIANGLE[triacount];
	if(!triangle)
	{
		if(!nophong)
		{
			delete [ ] tmpedges;
			delete [ ] tmpnorms;
		}
		return NULL;
	}

	t = triangle;
#else
#endif
	for(i=0; i<triacount; i++)
	{
#ifdef __STORM__
		t = new TRIANGLE;
		if(!t)
		{
			if(!nophong)
			{
				delete [ ] tmpedges;
				delete [ ] tmpnorms;
			}
			return NULL;
		}
#endif

		if(surfs)
			t->surf = surfs[i];
		else
			t->surf = srf;

		t->actor = actor;
		t->flags |= OBJECT_INBLOCK;
		t->Insert(rc);
#ifndef __STORM__
		t++;
#endif
	}
#ifndef __STORM__
	triangle->flags |= OBJECT_FIRSTBLOCK;
#else
	triangle = t;
#endif

	tria = mesh;
	t = triangle;
	for (i=0; i<triacount; i++)
	{
		p1 = edges[tria->e[0]].p[0];
		p2 = edges[tria->e[0]].p[1];
		if((p1 != edges[tria->e[1]].p[0]) &&
			(p2 != edges[tria->e[1]].p[0]))
		{
			p3 = edges[tria->e[1]].p[0];
		}
		else
		{
			p3 = edges[tria->e[1]].p[1];
		}

		if(!nophong)
		{
			t->vnorm = new VECTOR[3];
			if(!t->vnorm)
			{
				delete triangle;
				delete [ ] tmpedges;
				delete [ ] tmpnorms;
				return NULL;
			}

			t->vnorm[0] = tmpnorms[i];
			t->vnorm[1] = tmpnorms[i];
			t->vnorm[2] = tmpnorms[i];

			GenerateNormal(i, &t->vnorm[0], tmpnorms, tmpedges, p1, edges, mesh);
			GenerateNormal(i, &t->vnorm[1], tmpnorms, tmpedges, p2, edges, mesh);
			GenerateNormal(i, &t->vnorm[2], tmpnorms, tmpedges, p3, edges, mesh);

			rotmatrix->MultVectMat(&t->vnorm[0]);
			rotmatrix->MultVectMat(&t->vnorm[1]);
			rotmatrix->MultVectMat(&t->vnorm[2]);
		}

		t->p[0] = points[p1];
		matrix->MultVectMat(&t->p[0]);
		t->p[1] = points[p2];
		matrix->MultVectMat(&t->p[1]);
		t->p[2] = points[p3];
		matrix->MultVectMat(&t->p[2]);

#ifdef __STORM__
		t = (TRIANGLE*)t->GetNext();
#else
		t++;
#endif
		tria++;
	}
	if(!nophong)
	{
		delete [ ] tmpedges;
		delete [ ] tmpnorms;
	}
	return triangle;
}