bool hitTriang(Photon *photon, Triang *triang, const float distance, const Material *materials) { Shader shader = DIFFUSE; // Better idea? if (fDot(triang->direct, photon->direct) > -EPSILON) triang->direct = vNeg(triang->direct); // Update ray's position to the point where the ray hits the sphere photon->origin = fFMA(photon->direct, distance - UM(10), photon->origin); photon->lambda = materials[triang->mID].lambda; if (shader == CRAZY) { photon->direct = vNorm(vSub(newVec(0.99, 0, 0), photon->origin)); return REFLECTED; } else if (shader == SPECULAR) { // Angle between new and old vector is twice the angle between old vector and normal Vec reflect = vDot(photon->direct, triang->direct); photon->direct = vSub(photon->direct, vMul(triang->direct, vAdd(reflect, reflect))); return REFLECTED; } else if (shader == DIFFUSE) { photon->direct = randDir(); if (fDot(photon->direct, triang->direct) < EPSILON) photon->direct = vNeg(photon->direct); return REFLECTED; } else return ABSORBED; }
void QeFindPopularPasswords(LPCWSTR lpw, size_t n, std::vector<TqePatInsts>& vPatterns) { std::vector<WCHAR> vLower(n); std::vector<WCHAR> vLeet(n); for(size_t i = 0; i < n; ++i) { const WCHAR ch = lpw[i]; vLower[i] = towlower(ch); vLeet[i] = towlower(QeDecodeLeetChar(ch)); } const size_t nMaxLen = min(n, CPopularPasswords::GetMaxLength()); for(size_t nSubLen = nMaxLen; nSubLen >= 3; --nSubLen) { if(!CPopularPasswords::ContainsLength(nSubLen)) continue; std::vector<WCHAR> vSub(nSubLen); for(size_t i = 0; i <= (n - nSubLen); ++i) { if(QeVectorContains(vLower, L'\0', i, nSubLen)) continue; memcpy(&vSub[0], &vLower[i], nSubLen * sizeof(WCHAR)); if(!QeEvalAddPopularPasswordPattern(vPatterns, lpw, i, vSub, 0.0)) { memcpy(&vSub[0], &vLeet[i], nSubLen * sizeof(WCHAR)); if(QeEvalAddPopularPasswordPattern(vPatterns, lpw, i, vSub, 1.5)) memset(&vLower[i], 0, nSubLen * sizeof(WCHAR)); } else memset(&vLower[i], 0, nSubLen * sizeof(WCHAR)); } } }
float intersectTriang(const Triang *triang, const Photon *photon) { // 1. Intersect triangle plane // Distance d: // // (triang.origin - photon.origin) * triang.direct // d = ----------------------------------------------- // photon.direct * triang.direct // float d; d = fDot(vSub(triang->origin, photon->origin), triang->direct); d /= fDot(photon->direct, triang->direct); if (d < EPSILON) return MISS; // 2. Check if hit point is inside triangle // See: http://www.blackpawn.com/texts/pointinpoly/default.html // Compute vectors Vec vectap = vSub(fFMA(photon->direct, d, photon->origin), triang->origin); // Compute dot products // Crazy idea: precalculating, polymorphic virus style.. float dotCC = fDot(triang->vectac, triang->vectac); float dotCB = fDot(triang->vectac, triang->vectab); float dotCP = fDot(triang->vectac, vectap); float dotBB = fDot(triang->vectab, triang->vectab); float dotBP = fDot(triang->vectab, vectap); // Compute barycentric coordinates float invDenom = 1 / (dotCC * dotBB - dotCB * dotCB); float u = (dotBB * dotCP - dotCB * dotCP) * invDenom; float v = (dotCC * dotBP - dotCB * dotCP) * invDenom; // Check if point is in triangle if (triang->rectan) if (u > EPSILON && v > EPSILON && u < EPSILONONE && v < EPSILONONE) return d; else if (u > EPSILON && v > EPSILON && (u + v < EPSILONONE)) return d; return MISS; }
Intersect Triangle::intersect(Ray r) { Intersect::Intersect ret = *new Intersect::Intersect(); float a = v1.getX() - v2.getX(); float b = v1.getY() - v2.getY(); float c = v1.getZ() - v2.getZ(); float d = v1.getX() - v3.getX(); float e = v1.getY() - v3.getY(); float f = v1.getZ() - v3.getZ(); float g = r.getDir().at(0); float h = r.getDir().at(1); float i = r.getDir().at(2); float j = v1.getX() - r.getEye().at(0); float k = v1.getY() - r.getEye().at(1); float l = v1.getZ() - r.getEye().at(2); float eiminushf = e*i - h*f; float gfminusdi = g*f - d*i; float dhminuseg = d*h - e*g; float akminusjb = a*k - j*b; float jcminusal = j*c - a*l; float blminuskc = b*l - k*c; float m = a*(eiminushf) + b*(gfminusdi) + c*(dhminuseg); float beta = (j*(eiminushf) + k*(gfminusdi) + l*(dhminuseg))/m; if (beta < 0) {return ret;} float gamma = (i*(akminusjb) + h*(jcminusal) + g*(blminuskc))/m; if (gamma < 0 || beta+gamma > 1) {return ret;} float t = (-1)*(f*(akminusjb) + e*(jcminusal) + d*(blminuskc))/m; std::vector<float> p; std::vector<float> vec1 = v1.toVec(); std::vector<float> vec2 = v2.toVec(); std::vector<float> vec3 = v3.toVec(); std::vector<float> sub1 = vSub(&vec2, &vec1); std::vector<float> sub2 = vSub(&vec3, &vec1); std::vector<float> scaled1 = vScale(&beta, &sub1); std::vector<float> scaled2 = vScale(&gamma, &sub2); std::vector<float> added1 = vAdd(&vec1, &scaled1); p = vAdd(&added1, &scaled2); ret.setPoint(p); return ret; }
double intersectRectan(Rectan *rectan, Photon *photon) { // Clipping double dotProduct = vDotp(photon->direct, rectan->direct); if (dotProduct < EPSILON && dotProduct > -EPSILON) return MISS; // For explanation, see intersectCamera Vec vec = vSub(rectan->origin, photon->origin); double dist = vDotp(rectan->direct, vec) / dotProduct; if (dist < EPSILON) return MISS; /**************/ // Hit point on plane Vec point = vMul(photon->direct, dist); point = vAdd(photon->origin, point); point = vSub(point, rectan->origin); // Compute dot products double dotAA = vDotp(rectan->vectab, rectan->vectab); double dotBB = vDotp(rectan->vectad, rectan->vectad); double dotAB = vDotp(rectan->vectab, rectan->vectad); double dotAP = vDotp(rectan->vectab, point); double dotBP = vDotp(rectan->vectad, point); // Compute barycentric coordinates double denominator = 1 / (dotAA * dotBB - dotAB * dotAB); double u = (dotBB * dotAP - dotAB * dotBP) * denominator; double v = (dotAA * dotBP - dotAB * dotAP) * denominator; // Check if point is in rectangle if (u < EPSILON || v < EPSILON || u > EPSILONONE || v > EPSILONONE) return MISS; return dist; }
Photon triangEmit(const Triang *triang, const Material *materials) { Photon p; float u = drand48(), v = drand48(); Vec point = vAdd(fMul(triang->vectab, u), fMul(triang->vectac, v)); // If point is outside triangle if (!triang->rectan && u + v < EPSILONONE) p.origin = vSub(vAdd(triang->origin, vAdd(triang->vectab, triang->vectac)), point); else p.origin = vAdd(triang->origin, point); p.direct = randDir(); if (fDot(p.direct, triang->direct) > EPSILON) p.direct = vNeg(p.direct); p.lambda = materials[triang->mID].lambda; return p; }
void EnzBase::sub( double n ) { vSub( n ); }
void handleInput(GameState* gs, InputState* is) { double te = gs->frameSpan; float moveSpeed = gs->settings.keyScroll * te; // should load from config float rotateSpeed = gs->settings.keyRotate * te; // 20.8 degrees float keyZoom = gs->settings.keyZoom * te; float mouseZoom = gs->settings.mouseZoom * te; if(is->clickButton == 1) { /* flattenArea(gs->map.tb, gs->cursorPos.x - 5, gs->cursorPos.y - 5, gs->cursorPos.x + 5, gs->cursorPos.y + 5 ); setZone(&gs->map, gs->cursorPos.x - 5, gs->cursorPos.y - 5, gs->cursorPos.x + 5, gs->cursorPos.y + 5, gs->activeTool + 1 ); checkMapDirty(&gs->map); */ } if(is->buttonDown == 1) { gs->mouseDownPos.x = gs->cursorPos.x; gs->mouseDownPos.y = gs->cursorPos.y; printf("start dragging at (%d,%d)\n", (int)gs->cursorPos.x, (int)gs->cursorPos.y); } if(is->buttonUp == 1) { //vCopy(&gs->cursorPos, &gs->mouseDownPos); printf("stopped dragging at (%d,%d)\n", (int)gs->cursorPos.x, (int)gs->cursorPos.y); } if(is->clickButton == 2) { gs->activeTool = (gs->activeTool + 1) % 3; } // look direction if(is->keyState[38] & IS_KEYDOWN) { gs->direction += rotateSpeed; } if(is->keyState[39] & IS_KEYDOWN) { gs->direction -= rotateSpeed; } // keep rotation in [0,F_2PI) gs->direction = fmodf(F_2PI + gs->direction, F_2PI); // zoom if(is->keyState[52] & IS_KEYDOWN) { gs->zoom += keyZoom; gs->zoom = fmin(gs->zoom, -10.0); } if(is->keyState[53] & IS_KEYDOWN) { gs->zoom -= keyZoom; } if(is->clickButton == 4) { gs->zoom += mouseZoom; gs->zoom = fmin(gs->zoom, -10.0); } if(is->clickButton == 5) { gs->zoom -= mouseZoom; } // movement Vector move = { .x = moveSpeed * sin(F_PI - gs->direction), .y = moveSpeed * cos(F_PI - gs->direction), .z = 0.0f }; if(is->keyState[111] & IS_KEYDOWN) { vAdd(&gs->lookCenter, &move, &gs->lookCenter); } if(is->keyState[116] & IS_KEYDOWN) { vSub(&gs->lookCenter, &move, &gs->lookCenter); } // flip x and y to get ccw normal, using move.z as the temp move.z = move.x; move.x = -move.y; move.y = move.z; move.z = 0.0f; if(is->keyState[113] & IS_KEYDOWN) { vSub(&gs->lookCenter, &move, &gs->lookCenter); } if(is->keyState[114] & IS_KEYDOWN) { vAdd(&gs->lookCenter, &move, &gs->lookCenter); } if(is->keyState[110] & IS_KEYDOWN) { nearPlane += 50 * te; printf("near: %f, far: %f\n", nearPlane, farPlane); } if(is->keyState[115] & IS_KEYDOWN) { nearPlane -= 50 * te; printf("near: %f, far: %f\n", nearPlane, farPlane); } if(is->keyState[112] & IS_KEYDOWN) { farPlane += 250 * te; printf("near: %f, far: %f\n", nearPlane, farPlane); } if(is->keyState[117] & IS_KEYDOWN) { farPlane -= 250 * te; printf("near: %f, far: %f\n", nearPlane, farPlane); } static lastChange = 0; if(is->keyState[119] & IS_KEYDOWN) { if(gs->frameTime > lastChange + 1) { gs->debugMode = (gs->debugMode + 1) % 5; lastChange = gs->frameTime; } } } void setGameSettings(GameSettings* g, UserConfig* u) { const float rotateFactor = 0.7260f; const float scrollFactor = 300.0f; const float zoomFactor = 600.0f; g->keyRotate = rotateFactor * fclampNorm(u->keyRotateSensitivity); g->keyScroll = scrollFactor * fclampNorm(u->keyScrollSensitivity); g->keyZoom = zoomFactor * fclampNorm(u->keyZoomSensitivity); g->mouseRotate = rotateFactor * fclampNorm(u->mouseRotateSensitivity); g->mouseScroll = scrollFactor * fclampNorm(u->mouseScrollSensitivity); g->mouseZoom = 4 * zoomFactor * fclampNorm(u->mouseZoomSensitivity); printf("keyRotate %.3f\n", g->keyRotate); printf("keyScroll %.3f\n", g->keyScroll); printf("keyZoom %.3f\n", g->keyZoom); printf("mouseRotate %.3f\n", g->mouseRotate); printf("mouseScroll %.3f\n", g->mouseScroll); printf("mouseZoom %.3f\n", g->mouseZoom); } void setUpView(GameState* gs) { } void depthPrepass(XStuff* xs, GameState* gs, InputState* is) { // draw UI renderUIPicking(xs, gs); // draw terrain // TODO: factor all the math into the frame setup function //mScale3f(10, 10, 10, &mModel); //mRot3f(0, 1, 0, gs->direction, &mModel); msPush(&gs->proj); msPerspective(60, gs->screen.aspect, nearPlane, farPlane, &gs->proj); msPush(&gs->view); // order matters! don't mess with this. msTrans3f(0, -1, gs->zoom, &gs->view); msRot3f(1, 0, 0, F_PI / 6, &gs->view); msRot3f(0,1,0, gs->direction, &gs->view); msTrans3f(-gs->lookCenter.x, 0, -gs->lookCenter.y, &gs->view); // y-up to z-up rotation msRot3f(1, 0, 0, F_PI_2, &gs->view); msScale3f(1, 1, -1, &gs->view); // calculate cursor position Vector eyeCoord; Vector worldCoord; Matrix p, invp, invv; // device space (-1:1) Vector devCoord; devCoord.x = 0.50; devCoord.y = 0.50; devCoord.z = -1.0; // eye space mInverse(msGetTop(&gs->proj), &invp); vMatrixMul(&devCoord, &invp, &eyeCoord); vNorm(&eyeCoord, &eyeCoord); // world space mInverse(msGetTop(&gs->view), &invv); vMatrixMul(&eyeCoord, &invv, &worldCoord); vNorm(&worldCoord, &worldCoord); // draw terrain // drawTerrainBlockDepth(&gs->map, msGetTop(&gs->model), msGetTop(&gs->view), msGetTop(&gs->proj)); drawTerrainDepth(&gs->map, msGetTop(&gs->view), msGetTop(&gs->proj), &gs->screen.wh); msPop(&gs->view); msPop(&gs->proj); }
bool hitRectan(Photon *photon, Rectan *rectan, double distance) { // Specular reflection if (true) { // Update ray's position to the point where the ray hits the sphere Vec vec = vMul(photon->direct, distance); photon->origin = vAdd(photon->origin, vec); // Angle between new and old vector is twice the angle between old vector and normal vec = vMul(rectan->direct, vDotp(photon->direct, rectan->direct) * 2.f); vec = vSub(rectan->direct, photon->direct); photon->direct = vNorm(vec); // Might not be necessary... vec = vMul(photon->direct, 1000.f * EPSILON); photon->origin = vAdd(photon->origin, vec); return REFLECTED; } // Diffuse reflection else if (false) { // Necessary for adjusting direction of reflected photon later on bool positiveAngle = NO; if (vDotp(photon->direct, rectan->direct) > EPSILON) positiveAngle = YES; // Update ray's position to the point where the ray hits the sphere Vec vec = vMul(photon->direct, distance); photon->origin = vAdd(photon->origin, vec); #warning DEBUG!!! // Camera origin /*Vec origin; origin.x = 0.99f; origin.y = 0.f; origin.z = 0.f; Vec newDir; newDir = vSub(&origin, &photon->origin); photon->direct = vNorm(&newDir);*/ // Using spherical coordinate system to guarantee // uniform distribution of orientations in space double azimuth = drand48() * M_PI * 2; // "phi" double inclination = acos(2 * drand48() - 1); // "theta" photon->direct.x = sin(inclination) * cos(azimuth); photon->direct.y = sin(inclination) * sin(azimuth); photon->direct.z = cos(inclination); // Adjusting direction of reflected photon // Incoming positive -> negative outgoing // Incomi ng negative -> positive outgoing if (positiveAngle) { if (vDotp(photon->direct, rectan->direct) > EPSILON) photon->direct = vMul(photon->direct, -1.f); } else if (vDotp(photon->direct, rectan->direct) < -EPSILON) photon->direct = vMul(photon->direct, -1.f); photon->direct = vNorm(photon->direct); // Might not be necessary... vec = vMul(photon->direct, 1000.f * EPSILON); photon->origin = vAdd(photon->origin, vec); // Color photon->wavelength = rectan->mID; return REFLECTED; } /* * Absorption */ else return ABSORBED; }
Triang newTriABC(const Vec a, const Vec b, const Vec c, const bool rectan, const uint mID) { return newTriang(a, vSub(b, a), vSub(c, a), rectan, mID); }
void ReacBase::sub( double v ) { vSub( v ); }
Ray::Ray(std::vector<float> e, std::vector<float> p) { eye = e; point = p; camDir = vSub(p, e); }
//=============================================== // Unit Tests //=============================================== int main() { // set for command line argument -t to run unit tests. bool test = true; if (test) { std::cout<<"\n=================\nBegin UNIT TESTS\n=================\n\n"; Light::Light n = *new Light::Light(0, 1, 1, 0, 0.5, 0.5, 0.5); n.print(); Intersect::Intersect i = *new Intersect::Intersect(); if(i.isHit()) { std::cout<<"INCORRECT! hit is true.\n\n"; } else { std::cout<<"CORRECT! hit is false.\n\n"; i.setHit(true); } if(i.isHit()) { std::cout<<"CORRECT! hit is true.\n\n"; } else { std::cout<<"INCORRECT! hit is false.\n\n"; } std::vector<float> ptest(3); ptest[0] = 0; ptest[1] = 1; ptest[2] = 2; i.setPoint(ptest); std::vector<float> p = i.getPoint(); std::cout<< "[" << p[0] << ", " << p[1] << ", " << p[2] << "]\n"; Vertex::Vertex a = *new Vertex::Vertex(0,0,0); Vertex::Vertex b = *new Vertex::Vertex(1,0,0); Vertex::Vertex c = *new Vertex::Vertex(0,1,0); a.print(); a = a.sub(b); a.print(); std::vector<float> d = c.toVec(); std::cout<<"vec ["<< d[0] << ", " << d[1] << ", " << d[2] << "]\n"; Vertex::Vertex e1 = *new Vertex::Vertex(d); e1.print(); Vertex a1 = *new Vertex::Vertex(0,1,0); Vertex b1 = *new Vertex::Vertex(1,-1,0); Vertex c1 = *new Vertex::Vertex(-1,-1,0); Triangle t = *new Triangle::Triangle(a1,b1,c1); p[0] = 0; p[1] = 0; p[2] = 0; std::vector<float> e(3); e[0] = 0; e[1] = 0; e[2] = 3; Ray::Ray r = *new Ray::Ray(e, p); i = t.intersect(r); if (i.isHit()) { std::cout<<"Triangle Intersected - OKAY\n"; } Sphere::Sphere s = *new Sphere::Sphere(1, p); if (s.intersect(r).isHit()) { std::cout<<"Sphere Intersected - OKAY\n"; } e[0] = 0; e[1] = -4; e[2] = -4; p[0] = 1; p[1] = 1; p[2] = -1; r.setEye(e); r.setPoint(p); std::cout<<"projected "; vPrint(r.project(1.5)); PPM* ppm = new PPM(640, 480, 255); int val; for (float h = 0; h<480; h++) { for (float w =0; w<640; w++) { val = h;//std::min(255, (int)((w/639)*255.0f)); ppm->addPixel(*(new Pixel::Pixel(val, val, val))); } } ppm->save("output"); /* for (float h = 0; h < 3; h++) { for (float w = 0; w< ppm->getW(); w++) { std::cout<<w<<" "; ppm->getPixel(w, h).print(); } } */ std::cout<<"End PPM tests\n"; Pixel::Pixel px = *new Pixel::Pixel(255, 255, 255); Pixel::Pixel black = *new Pixel::Pixel(0,0,0); Pixel::Pixel pfloat = *new Pixel::Pixel(1.0f, 0.9f, 0.05f); Pixel::Pixel pmax = *new Pixel::Pixel(2.0f, 1.0f, 0.5f); px.print(); black.print(); black.add(px); black.print(); pfloat.print(); pmax.print(); std::vector<float> test1(3); test1[0] = 1; test1[1] = 0; test1[2] = 0.5; std::vector<float> test2(3); test2[0] = 0; test2[1] = 1; test2[2] = 0.5; std::cout<<vDot(test1, test2)<<"\n"; vPrint(vSub(test1, test2)); vPrint(vAdd(test1, test2)); vPrint(vMult(test1, test2)); vPrint(normalize(test1)); vPrint(normalize(test2)); vPrint(vCross(test1, test2)); vPrint(vScale(-1, test1)); std::cout<<"\n=================\nEnd UNIT TESTS\n=================\n\n"; return 0; } else { return 0; } }
// Get bounds according to different distance metrics int getBounds(float* S1r, float* S2r, const short& B, const Rset& R, float& lb, float& ub, const string dist) { // Get |A+| float* Apv = new float[B]; vSub(S1r + B*(R.hi[1]), S1r + B*(R.lo[0]-1), B, &Apv); float Ap = vSum(Apv,B) + EPS; // |A+| // Get |k+| float* Bpv = new float[B]; vSub(S2r + B*(R.hi[3]), S2r + B*(R.lo[2]-1), B, &Bpv); float Bp = vSum(Bpv, B) + EPS; // |B+| // Get |A-| float Am = EPS; // |A-| float* Amv = new float[B]; if (R.lo[1] >= R.hi[0]) { vSub(S1r + B*(R.lo[1]), S1r + B*(R.hi[0]-1), B, &Amv); Am += vSum(Amv, B); } else { memset(Amv, 0, sizeof(float)*B); } // Get |B-| float Bm = EPS; float* Bmv = new float[B]; if (R.lo[3] >= R.hi[2]) { vSub(S2r + B*(R.lo[3]), S2r + B*(R.hi[2]-1), B, &Bmv); Bm += vSum(Bmv, B); } else { memset(Bmv, 0, sizeof(float)*B); } lb = 0.0f; ub = 0.0f; short i; if (dist.compare("l1")==0) { for (i=0; i<B; i++) { lb += max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm); ub += max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp); } } else if (dist.compare("l2")==0) { for (i=0; i<B; i++) { lb += pow(max(0.0f, max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm)), 2.0f); ub += pow(max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp), 2.0f); } } else if (dist.compare("X2")==0) { for (i=0; i<B; i++) { lb += pow(max(0.0f, max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm)), 2.0f) \ / (Apv[i]/Am + Bpv[i]/Bm + EPS); ub += pow(max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp), 2.0f) \ / (Amv[i]/Ap + Bmv[i]/Bp + EPS); } } else if (dist.compare("int")==0) { for (i=0; i<B; i++) { lb -= min(Apv[i]/Am, Bpv[i]/Bm); ub -= min(Amv[i]/Ap, Bmv[i]/Bp); } } delete[] Apv; delete[] Bpv; delete[] Amv; delete[] Bmv; return 0; }