/******************************************************** Given a velocity vector and a position, it will test all objects found with the sps octree for collisions and return and new velocity that doesn't run through objects ********************************************************/ CWvec Collide::_get_move(CWpt& s, CWvec& vel) { if (_land == NULL) return vel; //transform source/velocty to object space Wpt source = _land->inv_xform() * s; Wvec velocity = _land->inv_xform() * vel; Wpt dest = source + velocity; //destination to travel to (obj space) double speed = velocity.length(); _hitFaces.clear(); double boxsize = _size * 5; Wvec d = Wvec(1,1,1)*boxsize; _camBox = BBOX(source - d, source + d); _hitFaces.clear(); //build collision list from the land buildCollisionList(_RootNode); //if(_hitFaces.num() != 0) // cout << "Faces Found: " << _hitFaces.num() << endl; //if there are no near by nodes then bring camera closer to the object if (_hitFaces.empty()) { Wvec force = _land->bbox().center() - dest; return velocity+(_size * .1 * log(force.length()) * force); } ARRAY<Wvec> norms; ARRAY<double> weights; double totalWeight = 0; //spring forces //weight all near by nodes for (int i = 0; i < _hitFaces.num(); i++) { Wpt p; _hitFaces[i]->bc2pos(_smplPoints[i],p); Wvec n = _hitFaces[i]->bc2norm(_smplPoints[i]); //get the projected distance of the camera and the surface point //against the normal of the surface point Wvec v = (dest - p).projected(n); double dist = n*v; //calculate the weight of given point weights.add(pow(e,sqr(dist))); totalWeight+=weights[i]; //calculate normal if (dist <= _size) //if its closer than it should be norms += speed * (_size - dist) * n; else //if its further than should be norms += speed * (_size - dist) * -n; } //calculate combination of all weighted norms Wvec force = Wvec(0,0,0); for (int i = 0; i < _hitFaces.num(); i++) force += (weights[i]/totalWeight) * norms[i]; //smooth forces so its not jerky double a = .1; _prevForce = force; force = ((1 - a) * (force - _prevForce)) +_pV; _pV = force; /* for (int i = 0; i < _hitFaces.num(); i++) { Wpt p; _hitFaces[i]->bc2pos(_smplPoints[i],p); Wvec n = _hitFaces[i]->bc2norm(_smplPoints[i]); Wvec v = ((source + (velocity + force)) - p).projected(n); double dist = n*v; if(dist < _size) velocity = velocity + (n *(_size - dist)); } */ return _land->xform() * (velocity + force); }
int main(int argc, char **argv) { RANDOM_Initialize(); uint start = 0; uint end = 0; printf(" STARTING FRAME : "); fflush(stdin); scanf("%d", &start); printf(" ENDING FRAME : "); fflush(stdin); scanf("%d", &end); fflush(stdin); if (start == end || start > end) return 0; SURFACE* marble_d = NULL; SURFACE* marble_n = NULL; SURFACE* marble_s = NULL; ImportBMPFile("data/marble_d.bmp", &marble_d); ImportBMPFile("data/marble_n.bmp", &marble_n); ImportBMPFile("data/marble_s.bmp", &marble_s); printf("\n"); printf("INITIALIZING SCENE\n\n"); VEC4 CameraPosition = VEC4(1.2f, 0.8f, -2.4f, 1.0); MainCamera = new Camera; MainCamera->position = CameraPosition; MainCamera->dimensions = VEC2(ViewWidth, ViewWidth * 0.75f); MainCamera->focalLength = 16.0f; MainCamera->sampleSize = Samples; Entity* diamond1 = new Entity; Entities.add(diamond1); diamond1->initialize(); ImportOBJFile("data/topDiamond.obj", &diamond1->mesh); diamond1->material->specular = 0.4f; diamond1->material->overlay = COLOR(0.05f, 0.4f, 1.0f, 1.0); diamond1->material->reflection = 1.0f; diamond1->material->refIndex = 1.333f; Entity* diamond2 = new Entity; Entities.add(diamond2); diamond2->initialize(); ImportOBJFile("data/bottomDiamond.obj", &diamond2->mesh); diamond2->material->specular = 0.4f; diamond2->material->overlay = COLOR(0.2f, 1.0f, 0.9f, 1.0); diamond2->material->reflection = 1.0f; diamond2->material->refIndex = 1.333f; Entity* background = new Entity; Entities.add(background); background->initialize(); ImportOBJFile("data/box.obj", &background->mesh); background->material->overlay = COLOR(0.7f, 1.0f, 0.9f, 1.0); background->material->reflection = 1.0f; background->material->specular = 0.4f; Light* light1 = new Light(VEC4(0.8f, 0.2f, -2.4f, 0.0f), VEC3(0.001f, 0.04f, 0.12f), COLOR(1.0f, 1.0f, 1.0f, 1.0f)); Lights.add(light1); light1->shadowIntensity = 0.8f; printf("START RENDERING\n\n"); SURFACE* render = NULL; CreateSurface(&render, "", Width, Height, PIXELFORMAT_RGB); char* filename = new char[128]; uint t = (uint)time(0); for (uint i = start; i < end; i++) { printf("RENDERING FRAME : %03d ", i); ClearBitmap(render, 0x333333); memset(filename, 0, sizeof(char) * 128); sprintf(filename, "RaySequence04_720p/RayTrace.%03d.bmp", i); Theta = float(i) * TurnSpeed; MainCamera->position = VEC4( (CameraPosition.x * cos(Theta)) - (CameraPosition.z * sin(Theta)), CameraPosition.y, (CameraPosition.x * sin(Theta)) + (CameraPosition.z * cos(Theta)), 1.0f); #if 0 light1->position = VEC4( (light1->position.x * cos(-Theta)) - (light1->position.z * sin(-Theta)), light1->position.y, (light1->position.x * sin(-Theta)) + (light1->position.z * cos(-Theta)), 1.0f); #endif //MainCamera->castRays(render); MainCamera->castRays(render); ExportBMPFile(filename, render); printf("DONE\n"); } delete [] filename; FreeSurface(&render); printf("\n"); //printf("FINISHED RENDERING\n\n"); return 0; }