void TrackBallManipulator::rotate(int posX, int posY) { Vec3 hitOld; int hit0 = hitSphere(mCurrentX,mCurrentY, hitOld); Vec3 hitNew; int hit1 = hitSphere(posX,posY,hitNew); if(hit0 != hit1) return; // if((hitNew - hitOld).length() / this->getRadius() > M_PI / 7) return; Vec3 center = getSceneGraph()->getCamera()->center(); Vec3 axis = (hitOld - center) ^ (hitNew - center); if(axis.Normalize() < ZERO_TOLERANCE) return; Scalar angle = (hitNew - hitOld).length() / this->getRadius(); Quat quat(axis,angle); getSceneGraph()->getCamera()->rotation_matrix() *= quat.convertToMatrix(); }
inline int Sphere::intersect( Ray &ray, float &t){ return hitSphere(ray, t); }
void hitObjects(Point3D_t rayO, Vector3D_t rayD,ShadeRec_t* sr) { int i; FLOAT_T t; Normal_t normal; Point3D_t localHitPoint; FLOAT_T tmin = kHugeValue; for(i = 0; i < nObjects; i++) { switch(objects[i]->type) { case SPHERE: if(hitSphere(rayO,rayD,&t,sr,objects[i]->center,objects[i]->radius) && (t < tmin)) { sr->hitAnObject = 1; tmin = t; sr->material = objects[i]->material; //sr.local_hit_point = ray.o + t * ray.d; sr->hitPoint.x = rayO.x + (t*rayD.x); sr->hitPoint.y = rayO.y + (t*rayD.y); sr->hitPoint.z = rayO.z + (t*rayD.z); normal.x = sr->normal.x; normal.y = sr->normal.y; normal.z = sr->normal.z; localHitPoint.x = sr->localHitPoint.x; localHitPoint.y = sr->localHitPoint.y; localHitPoint.z = sr->localHitPoint.z; } break; case PLANE: if(hitPlane(rayO,rayD,&t,sr,objects[i]->a,objects[i]->n) && (t < tmin)) { sr->hitAnObject = 1; tmin = t; sr->material = objects[i]->material; //sr.local_hit_point = ray.o + t * ray.d; sr->hitPoint.x = rayO.x + (t*rayD.x); sr->hitPoint.y = rayO.y + (t*rayD.y); sr->hitPoint.z = rayO.z + (t*rayD.z); normal.x = sr->normal.x; normal.y = sr->normal.y; normal.z = sr->normal.z; localHitPoint.x = sr->localHitPoint.x; localHitPoint.y = sr->localHitPoint.y; localHitPoint.z = sr->localHitPoint.z; } break; } } if(sr->hitAnObject) { sr->t = tmin; sr->normal.x = normal.x; sr->normal.y = normal.y; sr->normal.z = normal.z; sr->localHitPoint.x = localHitPoint.x ; sr->localHitPoint.y = localHitPoint.y ; sr->localHitPoint.z = localHitPoint.z ; } }
float ray(int n, float x0, float y0, float z0, float dx, float dy, float dz) { { const float xc = 0.0f, yc = 0.0f, zc = -6.0f, r = 1.0f; float x0c = x0 - xc; float y0c = y0 - yc; float z0c = z0 - zc; /* (x-xc)^2 + (y-yc)^2 + (z-zc)^2 = r^2; (x0c + dx * t)^2 + (y0c + dy * t)^2 + (z0c + dz * t)^2 = r^2; x0c^2 + 2*x0c*dx*t + dx^2*t^2 + y0c^2 + 2*y0c*dy*t + dy^2*t^2 + z0c^2 + 2 * z0c*dz*t + dz^2*t^2 = r^2 (dx^2 + dy^2 + dz^2)*t^2 + (2*x0c*dx + 2*y0c&dy + 2*z0c*dz) * t + x0c^2+y0c^2+z0c^2-r^2 */ float a = dx*dx + dy*dy + dz*dz; float b = 2*(x0c*dx + y0c*dy + z0c*dz); float c = x0c*x0c + y0c*y0c + z0c*z0c -r*r; float D = b*b - 4 * a * c; if(D >= 0) { float t = (-b - sqrtf(D)) / (2*a); if(t > 0) { float x = x0 + dx * t; float y = y0 + dy * t; float z = z0 + dz * t; float dx2 = x - xc; float dy2 = y - yc; float dz2 = z - zc; float l = dx2 * dx + dy2 * dy + dz2 * dz; l *= 2; float reflected; if(n) reflected = ray(n-1, x,y,z, dx - l*dx2, dy - l*dy2, dz - l*dz2); else reflected = 0.0f; float lambert = dx2 * lxn + dy2 * lyn + dz2 * lzn; if(lambert < 0.0f) lambert = 0.0f; return 0.2f + 0.4f * lambert + 0.4f * reflected; } } } if(dy < 0) { float t = (-1.5f - y0) / dy; float x = x0 + dx * t; float z = z0 + dz * t; float color; if( ((int)( floorf(x) ) + (int)( floorf(z) )) % 2 ) color = 0.8f; else color = 0.1f; float ts; if(hitSphere(x,-1.5f,z, lxn, lyn, lzn, &ts)) color *= 0.2f; float v = color + 0.5f * ray(n-1, x,-1.5f,z,dx,-dy,dz); if(v > 1.0f) return 1.0f; else return v; } float v = dy * 0.3f; if(v < 0.0f) return 0.0f; else return v; }