// 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; }
/* 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; }
// 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; }
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); }