object * newtri(void * tex, vector v0, vector v1, vector v2) { tri * t; vector edge1, edge2, edge3; VSub(&v1, &v0, &edge1); VSub(&v2, &v0, &edge2); VSub(&v2, &v1, &edge3); /* check to see if this will be a degenerate triangle before creation */ if ((VLength(&edge1) >= EPSILON) && (VLength(&edge2) >= EPSILON) && (VLength(&edge3) >= EPSILON)) { t=(tri *) rt_getmem(sizeof(tri)); t->nextobj = NULL; t->methods = &tri_methods; t->tex = (texture *)tex; t->v0 = v0; t->edge1 = edge1; t->edge2 = edge2; return (object *) t; } return NULL; /* was a degenerate triangle */ }
static void cylinder_normal(cylinder * cyl, vector * pnt, ray * incident, vector * N) { vector a,b,c; flt t; VSub((vector *) pnt, &(cyl->ctr), &a); c=cyl->axis; VNorm(&c); VDOT(t, a, c); b.x = c.x * t + cyl->ctr.x; b.y = c.y * t + cyl->ctr.y; b.z = c.z * t + cyl->ctr.z; VSub(pnt, &b, N); VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { /* make cylinder double sided */ N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
void EvalSinCos () { VecR t, tt, u, w; int j, n; VSetAll (t, 2. * M_PI); VDiv (t, t, region); DO_MOL { VMul (tt, t, mol[n].r); VSetAll (tCos[0][n], 1.); VSetAll (tSin[0][n], 0.); VSet (tCos[1][n], cos (tt.x), cos (tt.y), cos (tt.z)); VSet (tSin[1][n], sin (tt.x), sin (tt.y), sin (tt.z)); VSCopy (u, 2., tCos[1][n]); VMul (tCos[2][n], u, tCos[1][n]); VMul (tSin[2][n], u, tSin[1][n]); VSetAll (tt, 1.); VVSub (tCos[2][n], tt); for (j = 3; j <= fSpaceLimit; j ++) { VMul (w, u, tCos[j - 1][n]); VSub (tCos[j][n], w, tCos[j - 2][n]); VMul (w, u, tSin[j - 1][n]); VSub (tSin[j][n], w, tSin[j - 2][n]); } } }
static __inline__ void build_area_table(const BBOX_TREE *bbox_tree, Uint32 a, Uint32 b, float *areas) { VECTOR3 bmin, bmax, len; int i, j; VFill(bmin, BOUND_HUGE); VFill(bmax, -BOUND_HUGE); if (a < b) { for (i = a, j = 0; i <= b; i++, j++) { VMin(bmin, bmin, bbox_tree->items[i].bbox.bbmin); VMax(bmax, bmax, bbox_tree->items[i].bbox.bbmax); VSub(len, bmax, bmin); areas[j] = len[X] * len[Y] * len[Z]; } } else { for (i = a, j = a-b; i >= (int)b; i--, j--) { VMin(bmin, bmin, bbox_tree->items[i].bbox.bbmin); VMax(bmax, bmax, bbox_tree->items[i].bbox.bbmax); VSub(len, bmax, bmin); areas[j] = len[X] * len[Y] * len[Z]; } } }
float Vfunc(int which, float* v1, float* v2, float* vresult, float scalar) { int i = 0; float fTmp[3]; if (which == 2) { // vresult = v1 - v2 for (; i < 3; i++) vresult[i] = v1[i] - v2[i]; } if (which == 4) { // vresult = scalar * v1 for (; i < 3; ++i) vresult[i] = scalar * v1[i]; } if (which == 6) { // returns distance between v1 and v2 VSub(v1, v2, fTmp); // fTmp = v1 - v2 return VLen(fTmp); } if (which == 8) return acosf(VDot(v1, v2)/(VLen(v1) * VLen(v2)))*180.0/PI; if (which == 9) { // unit vector pointing from v1 toward v2 VSub(v2, v1, vresult); VUnit(vresult); } return 0; }
inline VECTOR MODEL :: getVector(){ VECTOR tmp = VSub(VGet(x, y, z), VGet(preX, preY, preZ)); if(tmp.x == 0 && tmp.z ==0) return VSub(VGet(x, y, z), VGet(ppX, ppY, ppZ)); ppX = preX; ppY = preY; ppZ = preZ; return VSub(VGet(x, y, z), VGet(preX, preY, preZ)); }
void ComputeSiteForces () { VecR dr, shift; real fcVal, rr, rrCut, rri, rri3, uVal; int j1, j2, m1, m2, ms1, ms2, n, typeSum; rrCut = Sqr (rCut); for (n = 0; n < nMol * sitesMol; n ++) VZero (site[n].f); uSum = 0.; for (m1 = 0; m1 < nMol - 1; m1 ++) { for (m2 = m1 + 1; m2 < nMol; m2 ++) { VSub (dr, mol[m1].r, mol[m2].r); VZero (shift); VShiftAll (dr); VVAdd (dr, shift); rr = VLenSq (dr); if (rr < rrCut) { ms1 = m1 * sitesMol; ms2 = m2 * sitesMol; for (j1 = 0; j1 < sitesMol; j1 ++) { for (j2 = 0; j2 < sitesMol; j2 ++) { typeSum = mSite[j1].typeF + mSite[j2].typeF; if (mSite[j1].typeF == mSite[j2].typeF || typeSum == 5) { VSub (dr, site[ms1 + j1].r, site[ms2 + j2].r); VVAdd (dr, shift); rr = VLenSq (dr); rri = 1. / rr; switch (typeSum) { case 2: rri3 = Cube (rri); uVal = 4. * rri3 * (rri3 - 1.); fcVal = 48. * rri3 * (rri3 - 0.5) * rri; break; case 4: uVal = 4. * bCon * sqrt (rri); fcVal = uVal * rri; break; case 5: uVal = -2. * bCon * sqrt (rri); fcVal = uVal * rri; break; case 6: uVal = bCon * sqrt (rri); fcVal = uVal * rri; break; } VVSAdd (site[ms1 + j1].f, fcVal, dr); VVSAdd (site[ms2 + j2].f, - fcVal, dr); uSum += uVal; } } } } } } }
void EvalRdf () { VecR dr, shift; real deltaR, normFac, rr; int j1, j2, k, m1, m2, ms1, ms2, n, rdfType, typeSum; if (countRdf == 0) { for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] = 0.; } } deltaR = rangeRdf / sizeHistRdf; for (m1 = 0; m1 < nMol - 1; m1 ++) { for (m2 = m1 + 1; m2 < nMol; m2 ++) { VSub (dr, mol[m1].r, mol[m2].r); VZero (shift); VShiftAll (dr); VVAdd (dr, shift); rr = VLenSq (dr); if (rr < Sqr (rangeRdf)) { ms1 = m1 * sitesMol; ms2 = m2 * sitesMol; for (j1 = 0; j1 < sitesMol; j1 ++) { for (j2 = 0; j2 < sitesMol; j2 ++) { typeSum = mSite[j1].typeRdf + mSite[j2].typeRdf; if (typeSum >= 2) { VSub (dr, site[ms1 + j1].r, site[ms2 + j2].r); VVAdd (dr, shift); rr = VLenSq (dr); if (rr < Sqr (rangeRdf)) { n = sqrt (rr) / deltaR; if (typeSum == 2) rdfType = 0; else if (typeSum == 3) rdfType = 1; else rdfType = 2; ++ histRdf[rdfType][n]; } } } } } } } ++ countRdf; if (countRdf == limitRdf) { normFac = VProd (region) / (2. * M_PI * Cube (deltaR) * Sqr (nMol) * countRdf); for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] *= normFac / Sqr (n - 0.5); } PrintRdf (stdout); countRdf = 0; } }
// キャラクターに当たっていたら押し出す処理を行う( chk_ch に ch が当たっていたら ch が離れる ) void Chara_Collision( CHARA *ch, VECTOR *ch_MoveVec, CHARA *chk_ch ) { VECTOR ChkChToChVec ; VECTOR PushVec ; VECTOR ChPosition ; float Length ; // 移動後の ch の座標を算出 ChPosition = VAdd( ch->Position, *ch_MoveVec ) ; // 当たっていなかったら何もしない if( HitCheck_Capsule_Capsule( ChPosition, VAdd( ChPosition, VGet( 0.0f, CHARA_HIT_HEIGHT, 0.0f ) ), CHARA_HIT_WIDTH, chk_ch->Position, VAdd( chk_ch->Position, VGet( 0.0f, CHARA_HIT_HEIGHT, 0.0f ) ), CHARA_HIT_WIDTH ) == TRUE ) { // 当たっていたら ch が chk から離れる処理をする // chk_ch から ch へのベクトルを算出 ChkChToChVec = VSub( ChPosition, chk_ch->Position ) ; // Y軸は見ない ChkChToChVec.y = 0.0f ; // 二人の距離を算出 Length = VSize( ChkChToChVec ) ; // chk_ch から ch へのベクトルを正規化( ベクトルの長さを 1.0f にする ) PushVec = VScale( ChkChToChVec, 1.0f / Length ) ; // 押し出す距離を算出、もし二人の距離から二人の大きさを引いた値に押し出し力を足して離れてしまう場合は、ぴったりくっつく距離に移動する if( Length - CHARA_HIT_WIDTH * 2.0f + CHARA_HIT_PUSH_POWER > 0.0f ) { float TempY ; TempY = ChPosition.y ; ChPosition = VAdd( chk_ch->Position, VScale( PushVec, CHARA_HIT_WIDTH * 2.0f ) ) ; // Y座標は変化させない ChPosition.y = TempY ; } else { // 押し出し ChPosition = VAdd( ChPosition, VScale( PushVec, CHARA_HIT_PUSH_POWER ) ) ; } } // 当たり判定処理後の移動ベクトルをセット *ch_MoveVec = VSub( ChPosition, ch->Position ) ; }
/* Vector ** Find_Required_Motion(Vector pt, FeaturePtr con) ** Returns the displacement required to make the pt satisfy the constraint. */ Vector Find_Required_Motion(Vector pt, FeaturePtr con) { Vector result; Vector temp_v; switch ( con->f_type ) { case plane_feature: temp_v = Closest_Plane_Point(con->f_vector, con->f_point, pt); break; case line_feature: temp_v = Closest_Line_Point(con->f_vector, con->f_point, pt); break; case point_feature: temp_v = con->f_point; break; default: VNew(0, 0, 0, result); } VSub(temp_v, pt, result); return result; }
void Compute_Cylinder_Data(OBJECT *Object) { DBL tmpf; VECTOR axis; CONE *Cone = (CONE *)Object; VSub(axis, Cone->apex, Cone->base); VLength(tmpf, axis); if (tmpf < EPSILON) { Error("Degenerate cylinder, base point = apex point."); } else { VInverseScaleEq(axis, tmpf); Compute_Coordinate_Transform(Cone->Trans, Cone->base, axis, Cone->apex_radius, tmpf); } Cone->dist = 0.0; /* Recalculate the bounds */ Compute_Cone_BBox(Cone); }
static void waves (const VECTOR EPoint, const TNORMAL *Tnormal, VECTOR normal, const TraceThreadData *Thread) { register unsigned int i; register DBL length, scalar, index, sinValue ; VECTOR point; for (i = 0 ; i < Thread->numberOfWaves ; i++) { VSub (point, EPoint, *Thread->waveSources[i]); VLength (length, point); if (length == 0.0) { length = 1.0; } index = length * Tnormal->Frequency * Thread->waveFrequencies[i] + Tnormal->Phase; sinValue = cycloidal(index); scalar = sinValue * Tnormal->Amount / Thread->waveFrequencies[i]; VAddScaledEq(normal, scalar / (length * (DBL)Thread->numberOfWaves), point); } }
void Parametric::Compute_BBox() { if(container_shape != 0) { Make_BBox(BBox, container.sphere.center[X] - container.sphere.radius, container.sphere.center[Y] - container.sphere.radius, container.sphere.center[Z] - container.sphere.radius, container.sphere.radius * 2, container.sphere.radius * 2, container.sphere.radius * 2); } else { // [ABX 20.01.2004] Low_Left introduced to hide BCC 5.5 bug BBOX_VECT& Low_Left = BBox.Lower_Left; Assign_BBox_Vect(Low_Left, container.box.corner1); VSub(BBox.Lengths, container.box.corner2, container.box.corner1); } if(Trans != NULL) { Recompute_BBox(&BBox, Trans); } }
void Bullet::Collision(Character* character) { for (l = 0; l < BULLET; l++) { if (bullet[l] == 1 | bullet[l] == 2 | bullet[l] == 3) { colVector = VSub(VGet(character->vector.x, character->vector.y + 40.0f, character->vector.z), bulletLocation[l]); distVector = colVector.x * colVector.x + colVector.y * colVector.y + colVector.z * colVector.z; if (isGraze[l] == 0 & distVector < 250) { if (bullet[l] == 1 | bullet[l] == 2) { character->AddMp(5); } if (bullet[l] == 3) { character->AddMp(15); } } if (distVector < 20) { if (bullet[l] == 1 | bullet[l] == 2) { bullet[l] = 0; character->AddHp(-10); } if (bullet[l] == 3) { bullet[l] = 0; character->AddHp(-30); } } } } }
Bullet::Bullet(VECTOR direction, VECTOR translation, int damage, float speed, BULLET_TYPE bulletType,float size) :Object(direction,translation) { _damage = damage; _size = size; _speed = speed; _bulletType = bulletType; _count = 0; _targetEnemy = NULL; _hit = false; if (_bulletType == BULLET_TYPE_PLAYER_HORMING) { float mdist = FLT_MAX; auto &enemies = ObjectField::getObjectField().Enemies; for (auto& enemy : enemies) { VECTOR v = VSub(_translation, enemy.GetTranslation()); float dist = VDot(v, v); if (mdist > dist) { mdist = dist; _targetEnemy = &enemy; } } } }
void ComputeForces () { VecR dr; real fcVal, rr, rrCut, rri, rri3; int j1, j2, n; rrCut = Sqr (rCut); DO_MOL VZero (mol[n].ra); uSum = 0.; virSum = 0.; for (j1 = 0; j1 < nMol - 1; j1 ++) { for (j2 = j1 + 1; j2 < nMol; j2 ++) { VSub (dr, mol[j1].r, mol[j2].r); VWrapAll (dr); rr = VLenSq (dr); if (rr < rrCut) { rri = 1. / rr; rri3 = Cube (rri); fcVal = 48. * rri3 * (rri3 - 0.5) * rri; VVSAdd (mol[j1].ra, fcVal, dr); VVSAdd (mol[j2].ra, - fcVal, dr); uSum += 4. * rri3 * (rri3 - 1.) + 1.; virSum += fcVal * rr; } } } }
void Torus::Normal(VECTOR Result, Intersection *Inter, TraceThreadData *Thread) const { DBL dist; VECTOR P, N, M; /* Transform the point into the torus space. */ MInvTransPoint(P, Inter->IPoint, Trans); /* Get normal from derivatives. */ dist = sqrt(P[X] * P[X] + P[Z] * P[Z]); if (dist > EPSILON) { M[X] = MajorRadius * P[X] / dist; M[Y] = 0.0; M[Z] = MajorRadius * P[Z] / dist; } else { Make_Vector(M, 0.0, 0.0, 0.0); } VSub(N, P, M); /* Transform the normalt out of the torus space. */ MTransNormal(Result, N, Trans); VNormalize(Result, Result); }
void Compute_IsoSurface_BBox(ISOSURFACE* IsoSurface) { if(IsoSurface->container_shape != 0) { Make_BBox(IsoSurface->BBox, IsoSurface->container.sphere.center[X] - IsoSurface->container.sphere.radius, IsoSurface->container.sphere.center[Y] - IsoSurface->container.sphere.radius, IsoSurface->container.sphere.center[Z] - IsoSurface->container.sphere.radius, IsoSurface->container.sphere.radius * 2, IsoSurface->container.sphere.radius * 2, IsoSurface->container.sphere.radius * 2); } else { // [ABX 20.01.2004] Low_Left introduced to hide BCC 5.5 bug BBOX_VECT& Low_Left = IsoSurface->BBox.Lower_Left; Assign_BBox_Vect(Low_Left, IsoSurface->container.box.corner1); VSub(IsoSurface->BBox.Lengths, IsoSurface->container.box.corner2, IsoSurface->container.box.corner1); } if(IsoSurface->Trans != NULL) { Recompute_BBox(&IsoSurface->BBox, IsoSurface->Trans); } }
static void Constraint_Update_Spec(FeatureSpecPtr spec, ObjectInstancePtr target, void *ptr, int abs) { Vector temp; ObjectInstancePtr src = (ObjectInstancePtr)ptr; if ( spec->spec_type == reference_spec && spec->spec_object == target ) { Edit_Remove_Obj_From_Dependencies(spec, src, NULL, 0); if ( abs ) { spec->spec_type = absolute_spec; Transform_Vector(target->o_transform, spec->spec_vector, spec->spec_vector); } else { spec->spec_type = offset_spec; Transform_Vector(target->o_transform, spec->spec_vector, temp); VSub(temp, src->o_world_verts[src->o_num_vertices - 1], spec->spec_vector); } } }
object * newgrid(int xsize, int ysize, int zsize, vector min, vector max) { grid * g; g = (grid *) rt_getmem(sizeof(grid)); memset(g, 0, sizeof(grid)); g->methods = &grid_methods; g->id = new_objectid(); g->xsize = xsize; g->ysize = ysize; g->zsize = zsize; g->min = min; g->max = max; VSub(&g->max, &g->min, &g->voxsize); g->voxsize.x /= (flt) g->xsize; g->voxsize.y /= (flt) g->ysize; g->voxsize.z /= (flt) g->zsize; g->cells = (objectlist **) rt_getmem(xsize*ysize*zsize*sizeof(objectlist *)); memset(g->cells, 0, xsize*ysize*zsize * sizeof(objectlist *)); /* fprintf(stderr, "New grid, size: %8d %8d %8d\n", g->xsize, g->ysize, g->zsize); */ return (object *) g; }
static void Smooth_Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter) { int Axis; DBL u, v; VECTOR PIMinusP1; SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object; VSub(PIMinusP1, Inter->IPoint, Triangle->P1); VDot(u, PIMinusP1, Triangle->Perp); if (u < EPSILON) { Assign_Vector(Result, Triangle->N1); return; } Axis = Triangle->vAxis; v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]); /* This is faster. [DB 8/94] */ Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X])); Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y])); Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z])); VNormalize(Result, Result); }
void Compute_Parametric_BBox(PARAMETRIC* Param) { if(Param->container_shape != 0) { Make_BBox(Param->BBox, Param->container.sphere.center[X] - Param->container.sphere.radius, Param->container.sphere.center[Y] - Param->container.sphere.radius, Param->container.sphere.center[Z] - Param->container.sphere.radius, Param->container.sphere.radius * 2, Param->container.sphere.radius * 2, Param->container.sphere.radius * 2); } else { // [ABX 20.01.2004] Low_Left introduced to hide BCC 5.5 bug BBOX_VECT& Low_Left = Param->BBox.Lower_Left; Assign_BBox_Vect(Low_Left, Param->container.box.corner1); VSub(Param->BBox.Lengths, Param->container.box.corner2, Param->container.box.corner1); } if(Param->Trans != NULL) { Recompute_BBox(&Param->BBox, Param->Trans); } }
void box_normal(const box * bx, const vector * pnt, const ray * incident, vector * N) { vector a, b, c; flt t; c.x=(bx->max.x + bx->min.x) / 2.0; c.y=(bx->max.y + bx->min.y) / 2.0; c.z=(bx->max.z + bx->min.z) / 2.0; VSub((vector *) pnt, &c, N); b=(*N); a.x=fabs(N->x); a.y=fabs(N->y); a.z=fabs(N->z); N->x=0.0; N->y=0.0; N->z=0.0; t=MYMAX(a.x, MYMAX(a.y, a.z)); if (t==a.x) N->x=b.x; if (t==a.y) N->y=b.y; if (t==a.z) N->z=b.z; VNorm(N); }
static __inline__ void build_area_table(BBOX_TREE *bbox_tree, Uint32 a, Uint32 b, float *areas) { int i, imin, dir; VECTOR3 bmin, bmax, len; if (a < b) { imin = a; dir = 1; } else { imin = b; dir = -1; } VFill(bmin, BOUND_HUGE); VFill(bmax, -BOUND_HUGE); for (i = a; i != (b + dir); i += dir) { VMin(bmin, bmin, bbox_tree->items[i].bbox.bbmin); VMax(bmax, bmax, bbox_tree->items[i].bbox.bbmax); VSub(len, bmax, bmin); areas[i - imin] = len[X] * len[Y] * len[Z]; } }
static __inline__ Uint32 check_aabb_aabb(const AABBOX bbox, const AABBOX dyn_bbox, float grow) { AABBOX new_bbox; VECTOR3 len; float old_v, new_v; VMin(new_bbox.bbmin, bbox.bbmin, dyn_bbox.bbmin); VMax(new_bbox.bbmax, bbox.bbmax, dyn_bbox.bbmax); VSub(len, bbox.bbmax, bbox.bbmin); old_v = len[X] * len[Y] * len[Z]; VSub(len, new_bbox.bbmax, new_bbox.bbmin); new_v = len[X] * len[Y] * len[Z]; if ((new_v / old_v) > grow) return 0; else return 1; }
double Distance_Point_To_Plane(Vector norm, Vector plane_pt, Vector pt) { Vector temp_v; VSub(pt, plane_pt, temp_v); return VDot(temp_v, norm); }
static int compute_smooth_triangle(SMOOTH_TRIANGLE *Triangle) { VECTOR P3MinusP2, VTemp1, VTemp2; DBL x, y, z, uDenominator, Proj; VSub(P3MinusP2, Triangle->P3, Triangle->P2); x = fabs(P3MinusP2[X]); y = fabs(P3MinusP2[Y]); z = fabs(P3MinusP2[Z]); Triangle->vAxis = max3_coordinate(x, y, z); VSub(VTemp1, Triangle->P2, Triangle->P3); VNormalize(VTemp1, VTemp1); VSub(VTemp2, Triangle->P1, Triangle->P3); VDot(Proj, VTemp2, VTemp1); VScaleEq(VTemp1, Proj); VSub(Triangle->Perp, VTemp1, VTemp2); VNormalize(Triangle->Perp, Triangle->Perp); VDot(uDenominator, VTemp2, Triangle->Perp); VInverseScaleEq(Triangle->Perp, -uDenominator); /* Degenerate if smooth normals are more than 90 from actual normal or its inverse. */ VDot(x,Triangle->Normal_Vector,Triangle->N1); VDot(y,Triangle->Normal_Vector,Triangle->N2); VDot(z,Triangle->Normal_Vector,Triangle->N3); if ( ((x<0.0) && (y<0.0) && (z<0.0)) || ((x>0.0) && (y>0.0) && (z>0.0)) ) { return(true); } Set_Flag(Triangle, DEGENERATE_FLAG); return(false); }
int click_line_bbox_intersection(const AABBOX bbox) { /* ALGORITHM: Use the separating axis * theorem to see if the line segment * and the box overlap. A line * segment is a degenerate OBB. */ VECTOR3 T, E; float r; VSub(T, bbox.bbmin, click_line.center); VSub(E, bbox.bbmax, bbox.bbmin); // do any of the principal axes // form a separating axis? if (fabs(T[X]) > (E[X] + click_line.length*fabs(click_line.direction[X]))) return 0; if (fabs(T[Y]) > (E[Y] + click_line.length*fabs(click_line.direction[Y]))) return 0; if (fabs(T[Z]) > (E[Z] + click_line.length*fabs(click_line.direction[Z]))) return 0; /* NOTE: Since the separating axis is * perpendicular to the line in these * last four cases, the line does not * contribute to the projection. */ // line.cross(x-axis)? r = E[Y]*fabs(click_line.direction[Z]) + E[Z]*fabs(click_line.direction[Y]); if (fabs(T[Y]*click_line.direction[Z] - T[Z]*click_line.direction[Y]) > r) return 0; // line.cross(y-axis)? r = E[X]*fabs(click_line.direction[Z]) + E[Z]*fabs(click_line.direction[X]); if( fabs(T[Z]*click_line.direction[X] - T[X]*click_line.direction[Z]) > r) return 0; // line.cross(z-axis)? r = E[X]*fabs(click_line.direction[Y]) + E[Y]*fabs(click_line.direction[X]); if (fabs(T[X]*click_line.direction[Y] - T[Y]*click_line.direction[X]) > r) return 0; return 1; }
static void sphere_normal(sphere * spr, vector * pnt, ray * incident, vector * N) { VSub((vector *) pnt, &(spr->ctr), N); VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { N->x=-N->x; N->y=-N->y; N->z=-N->z; } }
static void light_normal(point_light * l, vector * pnt, ray * incident, vector * N) { VSub((vector *) pnt, &(l->ctr), N); VNorm(N); if (VDot(N, &(incident->d)) > 0.0) { N->x=-N->x; N->y=-N->y; N->z=-N->z; } }