Ejemplo n.º 1
0
// pyramid
number CalculateVolumePyramid(const vector3& a, const vector3& b,
		const vector3& c, const vector3& d, const vector3& e) {
	number result = 0;
//	UG_LOG("a: " << a << " b: " << b << " c: " << c << " d: " << d << " e: " << e << endl)
	//fixme check for a set of volumes that this condition is met!
	// check a,b,c,d are in same plane
	// fixme why does this check only work in x,y plane?!
//	vector3 r, n, x;
//	VecCross(n, a, b);
//	VecNormalize(n, n);
//
//	VecSubtract(r, a, b);
//	VecSubtract(x, c, r);
//	number dot = VecDot(x, n);
//
//	UG_LOG("dot pyra: " << dot<< endl)
//	UG_ASSERT(dot < SMALL,
//			"pyramid volume calculation needs all base are points in one plane!");

	vector3 center, h_, h, c1, c2, da, ba, cb, cd;
	VecSubtract(da, d, a);
	VecSubtract(ba, b, a);
	VecSubtract(cb, c, b);
	VecSubtract(cd, c, d);
	VecCross(c1, da, ba);
	VecCross(c2, cb, cd);
	number A = 0.5 * VecLength(c1) + 0.5 * VecLength(c2);
//	UG_LOG("A pyra: " << A <<endl)

	vector3 arr[] = { a, b, c, d };
	CalculateCenter(center, arr, 4);

	number height = DistancePointToPlane(e, center, c1);

//	VecSubtract(h_, e, center);
//	VecAdd(h, h_, center);
//	VecSubtract(h, e, center);
//	 VecLength(h);
//	UG_LOG("pyra h: " << height << endl)

	result = 1.0 / 3.0 * A * height;
//	UG_LOG("pyra vol: " << result << endl)

	return result;
}
Ejemplo n.º 2
0
/* tracing */
static float vol_get_shadow(ShadeInput *shi, LampRen *lar, float *co)
{
	float visibility = 1.f;
	
	if(lar->shb) {
		float dxco[3]={0.f, 0.f, 0.f}, dyco[3]={0.f, 0.f, 0.f};
		
		visibility = testshadowbuf(&R, lar->shb, co, dxco, dyco, 1.0, 0.0);		
	} else if (lar->mode & LA_SHAD_RAY) {
		/* trace shadow manually, no good lamp api atm */
		Isect is;
		
		VecCopyf(is.start, co);
		if(lar->type==LA_SUN || lar->type==LA_HEMI) {
			is.vec[0] = -lar->vec[0];
			is.vec[1] = -lar->vec[1];
			is.vec[2] = -lar->vec[2];
			is.labda = R.maxdist;
		} else {
			VECSUB( is.vec, lar->co, is.start );
			is.labda = VecLength( is.vec );
		}

		is.mode = RE_RAY_MIRROR;
		is.skip = RE_SKIP_VLR_RENDER_CHECK | RE_SKIP_VLR_NON_SOLID_MATERIAL;
		
		if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW))
			is.lay= lar->lay;	
		else
			is.lay= -1;
			
		is.orig.ob = NULL;
		is.orig.face = NULL;
		is.last_hit = lar->last_hit[shi->thread];
		
		if(RE_rayobject_raycast(R.raytree,&is)) {
			visibility = 0.f;
		}
		
		lar->last_hit[shi->thread]= is.last_hit;
	}
	return visibility;
}
Ejemplo n.º 3
0
// Calculate plane equation given three vertecies on the plane.
//
void CGeometry::CalcPlaneEquation(D3DVECTOR *v0,D3DVECTOR *v1,D3DVECTOR *v2,D3DVECTOR *Normal,float *Offset)
{
	D3DVECTOR	refpt;
	D3DVECTOR	nvec;
	D3DVECTOR	tnorm;
	float	len;

// Compute the polygon's normal and a reference point on
// the plane. Note that the actual reference point is
// refpt / 3.

	nvec.x = (v0->y - v1->y) * (v0->z + v1->z);
	nvec.y = (v0->z - v1->z) * (v0->x + v1->x);
	nvec.z = (v0->x - v1->x) * (v0->y + v1->y);
	VecCopy(&refpt,v0);

	nvec.x += (v1->y - v2->y) * (v1->z + v2->z);
	nvec.y += (v1->z - v2->z) * (v1->x + v2->x);
	nvec.z += (v1->x - v2->x) * (v1->y + v2->y);
	VecInc(&refpt,v1);

	nvec.x += (v2->y - v0->y) * (v2->z + v0->z);
	nvec.y += (v2->z - v0->z) * (v2->x + v0->x);
	nvec.z += (v2->x - v0->x) * (v2->y + v0->y);
	VecInc(&refpt,v2);

// Normalize the polygon nvec to obtain the first
// three coefficients of the plane equation.

	len = (float)VecLength(&nvec);
	tnorm.x = nvec.x / len;
	tnorm.y = nvec.y / len;
	tnorm.z = nvec.z / len;

// Compute the last coefficient of the plane equation.

	len *= 3;
	*Offset = (float)(-VecDot(&refpt,&nvec) / len);
	Normal->x = tnorm.x;
	Normal->y = tnorm.y;
	Normal->z = tnorm.z;
}
Ejemplo n.º 4
0
Archivo: anim.c Proyecto: jinjoh/NOOR
void calc_curvepath(Object *ob)
{
	BevList *bl;
	BevPoint *bevp, *bevpn, *bevpfirst, *bevplast;
	PathPoint *pp;
	Curve *cu;
	Nurb *nu;
	Path *path;
	float *fp, *dist, *maxdist, xyz[3];
	float fac, d=0, fac1, fac2;
	int a, tot, cycl=0;
	

	/* in a path vertices are with equal differences: path->len = number of verts */
	/* NOW WITH BEVELCURVE!!! */
	
	if(ob==NULL || ob->type != OB_CURVE) return;
	cu= ob->data;
	if(cu->editnurb) 
		nu= cu->editnurb->first;
	else 
		nu= cu->nurb.first;
	
	if(cu->path) free_path(cu->path);
	cu->path= NULL;
	
	bl= cu->bev.first;
	if(bl==NULL || !bl->nr) return;

	cu->path=path= MEM_callocN(sizeof(Path), "path");
	
	/* if POLY: last vertice != first vertice */
	cycl= (bl->poly!= -1);
	
	if(cycl) tot= bl->nr;
	else tot= bl->nr-1;
	
	path->len= tot+1;
	/* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */
	if(path->len<nu->resolu*SEGMENTSU(nu)) path->len= nu->resolu*SEGMENTSU(nu);
	
	dist= (float *)MEM_mallocN((tot+1)*4, "calcpathdist");

		/* all lengths in *dist */
	bevp= bevpfirst= (BevPoint *)(bl+1);
	fp= dist;
	*fp= 0;
	for(a=0; a<tot; a++) {
		fp++;
		if(cycl && a==tot-1)
			VecSubf(xyz, bevpfirst->vec, bevp->vec);
		else
			VecSubf(xyz, (bevp+1)->vec, bevp->vec);
		
		*fp= *(fp-1)+VecLength(xyz);
		bevp++;
	}
	
	path->totdist= *fp;

		/* the path verts  in path->data */
		/* now also with TILT value */
	pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*4*path->len, "pathdata"); // XXX - why *4? - in 2.4x each element was 4 and the size was 16, so better leave for now - Campbell
	
	bevp= bevpfirst;
	bevpn= bevp+1;
	bevplast= bevpfirst + (bl->nr-1);
	fp= dist+1;
	maxdist= dist+tot;
	fac= 1.0f/((float)path->len-1.0f);
        fac = fac * path->totdist;

	for(a=0; a<path->len; a++) {
		
		d= ((float)a)*fac;
		
		/* we're looking for location (distance) 'd' in the array */
		while((d>= *fp) && fp<maxdist) {
			fp++;
			if(bevp<bevplast) bevp++;
			bevpn= bevp+1;
			if(bevpn>bevplast) {
				if(cycl) bevpn= bevpfirst;
				else bevpn= bevplast;
			}
		}
		
		fac1= *(fp)- *(fp-1);
		fac2= *(fp)-d;
		fac1= fac2/fac1;
		fac2= 1.0f-fac1;

		VecLerpf(pp->vec, bevp->vec, bevpn->vec, fac2);
		pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
		pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
		QuatInterpol(pp->quat, bevp->quat, bevpn->quat, fac2);
		NormalQuat(pp->quat);
		
		pp++;
	}
	
	MEM_freeN(dist);
}