void ClipPlanes::drawOtherSlicesInViewport(QGLViewer *viewer, int ic) { Vec voxelScaling = Global::voxelScaling(); Vec pos = m_clips[ic]->position(); Vec cxaxis = m_clips[ic]->m_xaxis; cxaxis = VECPRODUCT(cxaxis, voxelScaling); cxaxis.normalize(); Vec cyaxis = m_clips[ic]->m_yaxis; cyaxis = VECPRODUCT(cyaxis, voxelScaling); cyaxis.normalize(); Vec cnormal = m_clips[ic]->m_tang; cnormal = VECPRODUCT(cnormal, voxelScaling); cnormal.normalize(); float aspectRatio = viewer->aspectRatio(); float cdist = 2*viewer->sceneRadius()/m_clips[ic]->viewportScale(); float fov = viewer->camera()->fieldOfView(); float yf = cdist*tan(fov*0.5); float xf = yf*aspectRatio; Vec vc[4]; vc[0] = pos - xf*cxaxis - yf*cyaxis; vc[1] = pos + xf*cxaxis - yf*cyaxis; vc[2] = pos - xf*cxaxis + yf*cyaxis; vc[3] = pos + xf*cxaxis + yf*cyaxis; if (m_clips[ic]->showOtherSlice()) { glColor4f(0.5, 0.5, 0.5, 0.8); for (int tic=0; tic<m_clips.count(); tic++) { if (tic != ic) { Vec postic = m_clips[tic]->position(); Vec cnormaltic = m_clips[tic]->m_tang; cnormaltic = VECPRODUCT(cnormaltic, voxelScaling); cnormaltic.normalize(); int thickness = m_clips[tic]->thickness(); Vec cc = m_clips[tic]->color(); glLineWidth(3); glColor4f(cc.x*0.5, cc.y*0.5, cc.z*0.5, 0.5); drawViewportIntersections(postic-thickness*cnormaltic, cnormaltic, vc); glLineWidth(2); glColor4f(cc.x*0.7, cc.y*0.7, cc.z*0.7, 0.7); drawViewportIntersections(postic, cnormaltic, vc); glLineWidth(1); glColor4f(cc.x*0.5, cc.y*0.5, cc.z*0.5, 0.5); drawViewportIntersections(postic+thickness*cnormaltic, cnormaltic, vc); } } } }
/** Cast reflected ray ** @param ray incoming ray ** @param pt intersection point ** @param normal normal of pt ** @return reflected ray **/ Ray reflect(Ray ray, Vec pt, Vec normal){ Vec v = ray.getOrig() - pt; v = v.normalize(); Vec dir = normal * (2 * v.dot(normal)) - v; dir = dir.normalize(); // reflected direction Ray t(pt, dir, 0, 9999, ReflectedRay); if (debugMode) { printf("reflected ray: origin = "); t.getOrig().print(); printf("reflected ray: direction = "); t.getDir().print(); } return t; }
Angle Client::calcPlayerObjAngle(Vec2<int> mouseScreenPos) { if (worldModel.getPlayerObjs().exists(playerId)) { PlayerObj *playerObj = (worldModel.getPlayerObjs())[playerId]; float angle; Pos mousePos(viewportHandler.screenToGame(worldRenderer.getRenderArea(playerObj), mouseScreenPos)); Vec aimVec = mousePos - playerObj->pos; aimVec.normalize(); if ((aimVec.x > 0.5) || (aimVec.x < 0.5f)) { angle = asin(aimVec.y); if (aimVec.x < 0.0f) angle = PI_F - angle; } else { angle = acos(aimVec.x); if (aimVec.y < 0.0f) angle = -angle; } return angle; } return 0.0f; }
//alg for calculating shading. Calls diffuseShade and SpecularShade Color RT_lights(Figure* obj, const Ray& ray, const Vec& thePoint, const Vec& normal) { Color c = Color(); for (list<Light*>::iterator iterator = lightList.begin(), end = lightList.end(); iterator != end; ++iterator) { Light* theLight = *iterator; pair<double, Figure*> inter = nearestIntersection(Ray(Vec(thePoint), theLight->getPos()), MIN_T / SHAD_RES, 1.0, EPSILON, false); if (inter.first <= 0) { Vec* toLight = thePoint.normalize(theLight->getPos()); double dotProduct = toLight->dot(normal); Vec* subt = (thePoint.sub(theLight->getPos())); double dist = abs(subt->getMag()); Color dif = diffuseShade(obj, theLight, max(dotProduct, 0.0), dist); Vec* Q = normal.scale(normal.dot(*toLight)); Vec* S = Q->sub(*toLight); Vec* S2 = S->scale(2.0); Vec* R = toLight->add(*S2); Vec* norm = ray.getNorm(); Vec* scaledNorm = norm->scale(-1.0); dotProduct = max(0.0, R->dot(*scaledNorm)); Color spec = specularShade(obj, normal, theLight, *toLight, pow(dotProduct, obj->getShininess()), ray, dist); c = c.add(dif.add(spec)); delete(toLight); delete(Q); delete(S); delete(R); delete(S2); delete(subt); delete(norm); delete(scaledNorm); } } return c; }
void GiLightObject::makePlanar(int v0, int v1, int v2) { int npoints = m_points.count(); if (npoints < 3) return; Vec cen = m_points[0]; for(int i=1; i<npoints; i++) cen += m_points[i]; cen /= npoints; Vec normal; normal = (m_points[v0]-m_points[v1]).unit()^(m_points[v2]-m_points[v1]).unit(); normal.normalize(); // now shift all points into the plane for(int i=0; i<npoints; i++) { Vec v0 = m_points[i]-cen; float dv = normal*v0; m_points[i] -= dv*normal; } computeTangents(); m_updateFlag = true; m_lightChanged = true; // for light recomputation m_undo.append(m_points); }
void Seaweed::createSystemScene() { Particle *p1, *p2; // add a fixed particle Vec initPos = Vec(0.5, 0.5, 0.0); // just use the first point p1 = new Particle(initPos, Vec(), 0.0, particleRadius); particles.push_back(p1); // init velocity is null and so is the weght. The particle can not move then, it will be the root of seaweed // add a set of particles particles Vec pos1 = initPos; for(int i = 1; i< NB_PARTICLE; i++) { float positionCurve = i*(1.0/NB_PARTICLE); Vect3d * pos1Curve = new Vect3d(pos1.x,pos1.y,pos1.z); control->get_pos(pos1Curve, positionCurve); Vec vel1; if(i%2) { vel1 = Vec(0.0, defaultVelocity, 0.0); // non null initial velocity on y axis(lateral movement) } else { vel1 = Vec(0.0, -defaultVelocity*0.8, 0.0); // non null initial velocity on y axis(lateral movement) } p2 = new Particle(Vec(pos1Curve->x,pos1Curve->y,pos1Curve->z), vel1, 0.1, particleRadius); // No gravity now particles.push_back(p2); // add a spring between the two particle Vec u = p2->getPosition() - p1->getPosition(); Spring *s = new Spring(p1, p2, 5.0, u.normalize()+(rand()%10)/80.0 , 1.5); // add a string between the two created particle springs.push_back(s); p1 = p2; } // .. then create a chain of particles }
static int trimesh(lua_State *ls) { if (!lua_istable(ls, -1)) { luaL_error(ls, "trimesh: expected table"); } std::vector<Vec> vertices; lua_getfield(ls, -1, "vertices"); lua_pushnil(ls); while (lua_next(ls, -2) != 0) { double x, y, z; get_xyz(ls, x, y, z); vertices.push_back(Vec{x, y, z}); lua_pop(ls, 1); } lua_pop(ls, 1); std::vector<TriangleMesh::Face> faces; lua_getfield(ls, -1, "faces"); lua_pushnil(ls); while (lua_next(ls, -2) != 0) { size_t i, j, k; lua_getfield(ls, -1, "i"); i = static_cast<size_t>(luaL_checknumber(ls, -1)); lua_pop(ls, 1); lua_getfield(ls, -1, "j"); j = static_cast<size_t>(luaL_checknumber(ls, -1)); lua_pop(ls, 1); lua_getfield(ls, -1, "k"); k = static_cast<size_t>(luaL_checknumber(ls, -1)); lua_pop(ls, 1); Vec ab = vertices[j] - vertices[i]; Vec ac = vertices[k] - vertices[i]; Vec norm = ab.cross(ac); norm.normalize(); faces.push_back(TriangleMesh::Face{i, j, k, norm}); lua_pop(ls, 1); } lua_pop(ls, 1); lua_getfield(ls, -1, "material"); Material *mat = reinterpret_cast<Material *>(lua_touserdata(ls, -1)); lua_pop(ls, 1); TriangleMesh *tm = new TriangleMesh; tm->faces = std::move(faces); tm->vertices = std::move(vertices); tm->material.reset(mat); lua_pushlightuserdata(ls, tm); return 1; }
void RigidBody::step(double dt){ FILE_LOG(logDEBUG)<<"entered RigidBody::step(double dt)"<<std::endl; // set com // NOTE: com is transform r in THIS case for(unsigned i=0;i<3;i++) com[i] = Tws(i,3); // NOTE: set accel for integration function vd_ = &vd; FILE_LOG(logDEBUG) << "q (before) = " << q << std::endl; FILE_LOG(logDEBUG) << "v (before) = " << v << std::endl; FILE_LOG(logDEBUG) << "vd (before) = " << vd << std::endl; // Set forces to apply // apply drag force { double k = 0.1; Ravelin::Vector3d drag; v.get_sub_vec(0,3,drag); drag = -drag *= (drag.dot(drag) * k); apply_force(drag,com); } // apply forces calc_fwd_dynamics(); // Set up state Vec state; state.set_zero(q.rows() + v.rows()); state.set_sub_vec(0,q); state.set_sub_vec(q.rows(),v); // Integrate state forward 1 step sim_->integrate(sim_->time,dt,&fn,state); // re-normalize quaternion state state.get_sub_vec(0,q.rows(),q); state.get_sub_vec(q.rows(),state.rows(),v); Vec e; q.get_sub_vec(3,7,e); e.normalize(); q.set_sub_vec(3,e); FILE_LOG(logDEBUG) << "q (after) = " << q << std::endl; FILE_LOG(logDEBUG) << "v (after) = " << v << std::endl; FILE_LOG(logDEBUG) << "vd (after) = " << vd << std::endl; // Update graphics transform update(); FILE_LOG(logDEBUG)<<"exited RigidBody::step(.)"<<std::endl; reset_accumulators(); }
void Charge::drawLabel(QGLViewer& viewer, QFontMetrics& fontMetrics) { Vec pos(getPosition()); Vec shift = viewer.camera()->position() - pos; shift.normalize(); pos = pos + 1.05 * shift * getRadius(true); pos = viewer.camera()->projectedCoordinatesOf(pos); pos.x -= fontMetrics.width(m_label)/2; pos = viewer.camera()->unprojectedCoordinatesOf(pos); viewer.renderText(pos[0], pos[1], pos[2], m_label); }
template<class Vec> void testNormalize() { Vec vec; for (unsigned int i = 0; i < vec.getDimension(); i++) vec[i] = numbers[i]; // getNormalized auto temp = vec.getNormalized(); ASSERT(dbgl::isSimilar(temp.getLength(), 1.0f)); // normalize vec.normalize(); ASSERT(dbgl::isSimilar(vec.getLength(), 1.0f)); }
/** Main function **/ int main(int argc, char **argv) { if (argc != 2) { printf("usage:\t./hw6 filename\n"); exit(0); } // Read .in file for (int i = 1; i < argc; i++) scene.readfile(argv[i]); scene.print(); // Create screen img = new Image(scene.w, scene.h); float pix[3] = {0.0, 0.0, 0.0}; Vec wp[9]; Vec rayDirection; Ray rays[9]; Vec pixColor[9]; // Camera frame parameters img->setCamera(scene.eyePos, scene.at, scene.up); // for each pixel on the screen for (int i=0; i<scene.w; i++) { for (int j=0; j<scene.h; j++) { // supersampling for 9 rays per pixel for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { int idx = row*3 + col; wp[idx] = img->normalizePixel(Vec(i+0.5*row,j+0.5*col,0), scene.fovy); rayDirection = wp[idx] - img->cf.eyePos; rayDirection = rayDirection.normalize(); rays[idx] = Ray(scene.eyePos, rayDirection, 0, 9999, CameraRay); pixColor[idx] = trace(rays[idx], 4); } } // set debug mode if (i==scene.w/2 && j==scene.h/2+1) debugMode = 0; else debugMode = 0; // output color info Vec color = (pixColor[0] + pixColor[2] + pixColor[6] + pixColor[8]) * (1.0/16) + (pixColor[1] + pixColor[3] + pixColor[5] + pixColor[7]) * (1.0/8) + pixColor[4] * (1.0/4); pix[0] = color.x; pix[1] = color.y; pix[2] = color.z; img->setPixel(pix, i, j); } } // Write pixel color to ppm file img->writeToPPM(scene.outname); return 0; }
void draw_model ( const Model& m, bool smooth) { glEnable(GL_NORMALIZE); if(App->wireframe){glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);} else glPolygonMode(GL_FRONT, GL_FILL); glBegin(GL_TRIANGLES); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); if(smooth) { for(int i = 0; i < m.fsize; i++) { glColor3d(m.F[i].r/255.0, m.F[i].g/255.0, m.F[i].b/255.0); glNormal3d(m.N[m.F[i].na].x, m.N[m.F[i].na].y, m.N[m.F[i].na].z); glVertex3d(m.V[m.F[i].va].x, m.V[m.F[i].va].y, m.V[m.F[i].va].z); glNormal3d(m.N[m.F[i].nb].x, m.N[m.F[i].nb].y, m.N[m.F[i].nb].z); glVertex3d(m.V[m.F[i].vb].x, m.V[m.F[i].vb].y, m.V[m.F[i].vb].z); glNormal3d(m.N[m.F[i].nc].x, m.N[m.F[i].nc].y, m.N[m.F[i].nc].z); glVertex3d(m.V[m.F[i].vc].x, m.V[m.F[i].vc].y, m.V[m.F[i].vc].z); } glEnd(); } if(!smooth) { for(int i = 0; i < m.fsize; i++) { glColor3d(m.F[i].r/255.0, m.F[i].g/255.0, m.F[i].b/255.0); Vec u = m.V[m.F[i].vb] - m.V[m.F[i].va]; Vec v = m.V[m.F[i].vb] - m.V[m.F[i].vc]; Vec w = cross(v, u); w.normalize(); glNormal3d(w.x, w.y, w.z); glVertex3d(m.V[m.F[i].va].x, m.V[m.F[i].va].y, m.V[m.F[i].va].z); glVertex3d(m.V[m.F[i].vb].x, m.V[m.F[i].vb].y, m.V[m.F[i].vb].z); glVertex3d(m.V[m.F[i].vc].x, m.V[m.F[i].vc].y, m.V[m.F[i].vc].z); } glEnd(); } }
void Atom::drawLabel(Viewer& viewer, LabelType const type, QFontMetrics& fontMetrics) { Vec pos(getPosition()); Vec shift = viewer.camera()->position() - pos; shift.normalize(); QString label(getLabel(type)); pos = pos + 1.05 * shift * getRadius(true); pos = viewer.camera()->projectedCoordinatesOf(pos); pos.x -= fontMetrics.width(label)/2.0; pos.y += fontMetrics.height()/4.0; pos = viewer.camera()->unprojectedCoordinatesOf(pos); glColor3f(0.1, 0.1, 0.1); viewer.renderText(pos[0], pos[1], pos[2], label, viewer.labelFont()); }
int main(int argc, char** argv) { GLubyte *pic; createSceneFromFile(); time_t start; time_t end; time(&start); pic = scene->camera->getPicture(*scene, *intersectionFinder); time(&end); double diff = difftime(end, start); printf("Rendering time in seconds: %lf\n", diff); Display display(width, height, "RayTracing"); display.setPicture(pic); display.show(); delete intersectionFinder; delete pic; delete scene; return 0; Vec a(-1, -1, 0); Vec n(0, 1, 0); a.normalize(); n.normalize(); Vec r = (a - 2 * ((a) * n) * n); float c = 0; while (c < M_PI / 2){ Vec r = (a*c - 2 * ( (a*c) * n) * n); r.normalize(); c += 0.1; if (n*r<=0){ c += 0; } } return 0; }
Vec Spring::getCurrentForce() const { // we compute the force applied on particle 1 by particle 2 Vec u = p1->getPosition() - p2->getPosition(); double uNorm = u.normalize(); // u is thereafter normalized! if (uNorm < 1.0e-6) return Vec(); // null force // force due to stiffness only Vec sF = -stiffness * (uNorm - equilibriumLength) * u; // damping force Vec dF = -damping * ((p1->getVelocity() - p2->getVelocity()) * u) * u; return sF + dF; }
void draw_segment(volume<short>& image, const Pt& p1, const Pt& p2) { double xdim = (double) image.xdim(); double ydim = (double) image.ydim(); double zdim = (double) image.zdim(); double mininc = min(xdim,min(ydim,zdim)) * .5; Vec n = p1 - p2; double d = n.norm(); n.normalize(); for (double i=0; i<=d; i+=mininc) { Pt p = p2 + i* n; image((int) floor((p.X)/xdim +.5),(int) floor((p.Y)/ydim +.5),(int) floor((p.Z)/zdim +.5)) = 1; } }
bool SubdivScene::repositionSelectedVertex(int x, int y) { if (!selectedVertex) return false; printf("Repositioning vertex, (%i, %i)...\n", x,y); //In the plane perpendicular to camera->look, and through which the vertex passes, //move vertex from where it is to where the mouse is //Use current vertex position to calculate the center of the screen Vec camPos = camera->getPos(); Vec vPos = selectedVertex->getData().p; Vec diff = vPos - camPos; Vec look = camera->getLook().normalize(); float cosAngle = sqrt(diff.normalize().dot(look)); float lookLength = diff.length()*cosAngle; Vec centreDiff = look*lookLength; Vec diffInPlane = vPos - (camPos + centreDiff); printf(" diffInPlane is"); diffInPlane.print(); printf(" Cam pos is"); camPos.print(); float anglex = (x - Globals::getWidth()/2)*Globals::getFovx() * Globals::PI/180/Globals::getWidth(); float angley = (y - Globals::getHeight()/2)*Globals::getFovy() * Globals::PI/180/Globals::getHeight(); float hLength = tan(anglex)*centreDiff.length(); float vLength = tan(angley)*centreDiff.length(); printf(" anglex is %f and angley is %f, fovx is %f\n", anglex, angley, Globals::getFovx()); printf(" hLength is %f and vLength is %f, hrat is %i\n", hLength, vLength, x - Globals::getWidth()/2); //calculate the shifts in the horiz and vertical directions Vec right = camera->getLook().cross(camera->getUp()).normalize()*hLength; Vec up = camera->getUp().normalize()*vLength; printf(" Right is"); right.print(); printf(" up is"); up.print(); Vec newPos = vPos + right + up - diffInPlane; selectedVertex->getData().p = newPos; printf(" Old position was (%f, %f, %f)\n", vPos.x, vPos.y, vPos.z); printf(" New position is (%f, %f, %f)\n", newPos.x, newPos.y, newPos.z); redrawRequired = true; }
int main(int argc, char *argv[]) { int nworkers = omp_get_num_procs(); omp_set_num_threads(nworkers); rng.init(nworkers); int w = 480, h = 360, samps = argc==2 ? atoi(argv[1])/4 : 1; // # samples Vec cx = Vec(w*.5135/h), cy = (cx.cross(cam.d)).normalize()*.5135; std::vector<Vec> c(w*h); #pragma omp parallel for schedule(dynamic, 1) for ( int y = 0; y < h; y++ ) { for ( int x = 0; x < w; x++ ) { const int i = (h - y - 1)*w + x; for ( int sy = 0; sy < 2; ++sy ) { for ( int sx = 0; sx < 2; ++sx ) { Vec r; for ( int s = 0; s<samps; s++ ) { double r1 = 2*rng(), dx = r1<1 ? sqrt(r1)-1 : 1-sqrt(2-r1); double r2 = 2*rng(), dy = r2<1 ? sqrt(r2)-1 : 1-sqrt(2-r2); Vec d = cx*(((sx+.5 + dx)/2 + x)/w - .5) + cy*(((sy+.5 + dy)/2 + y)/h - .5) + cam.d; r = r + receivedRadiance(Ray(cam.o, d.normalize()), 1, true)*(1./samps); } c[i] = c[i] + Vec(clamp(r.x), clamp(r.y), clamp(r.z))*.25; } } } #pragma omp critical fprintf(stderr,"\rRendering (%d spp) %6.2f%%",samps*4,100.*y/(h-1)); } fprintf(stderr, "\n"); // Write resulting image to a PPM file FILE *f = fopen("image.ppm", "w"); fprintf(f, "P3\n%d %d\n%d\n", w, h, 255); for ( int i = 0; i<w*h; i++ ) fprintf(f, "%d %d %d ", toInt(c[i].x), toInt(c[i].y), toInt(c[i].z)); fclose(f); return 0; }
bool ClipPlanes::viewportKeypressEvent(int i, QKeyEvent *event) { if (i >= 0 && i < m_clips.count()) { if (event->key() == Qt::Key_Delete) { QMessageBox::information(0, "", "Switching off the viewport"); m_clips[i]->setViewport(QVector4D(-1,-1,-1,-1)); return true; } bool ok = m_clips[i]->keyPressEvent(event); if (ok) { if (m_clips[i]->mopClip()) { Vec pos = m_clips[i]->position(); Vec normal = m_clips[i]->m_tang; Vec voxelScaling = Global::voxelScaling(); normal = VECPRODUCT(normal, voxelScaling); normal.normalize(); pos = VECPRODUCT(pos, voxelScaling); emit mopClip(pos, normal); } if (m_clips[i]->saveSliceImage()) emit saveSliceImage(i, m_clips[i]->resliceSubsample()); else if (m_clips[i]->resliceVolume()) { int subsample = m_clips[i]->resliceSubsample(); int tagvalue = m_clips[i]->resliceTag(); emit extractClip(i, subsample, tagvalue); } else if (m_clips[i]->reorientCamera()) emit reorientCameraUsingClipPlane(i); } return ok; } return false; }
void draw_mesh(volume<short>& image, const Mesh &m) { double xdim = (double) image.xdim(); double ydim = (double) image.ydim(); double zdim = (double) image.zdim(); double mininc = min(xdim,min(ydim,zdim)) * .5; for (list<Triangle*>::const_iterator i = m._triangles.begin(); i!=m._triangles.end(); i++) { Vec n = (*(*i)->get_vertice(0) - *(*i)->get_vertice(1)); double d = n.norm(); n.normalize(); for (double j=0; j<=d; j+=mininc) { Pt p = (*i)->get_vertice(1)->get_coord() + j* n; draw_segment(image, p, (*i)->get_vertice(2)->get_coord()); } } }
volume<float> draw_mesh_bis(const volume<float>& image, const Mesh &m) { double xdim = (double) image.xdim(); double ydim = (double) image.ydim(); double zdim = (double) image.zdim(); double mininc = min(xdim,min(ydim,zdim)) * .5; volume<float> res = image; double max = image.max(); for (list<Triangle*>::const_iterator i = m._triangles.begin(); i!=m._triangles.end(); i++) { Vec n = (*(*i)->get_vertice(0) - *(*i)->get_vertice(1)); double d = n.norm(); n.normalize(); for (double j=0; j<=d; j+=mininc) { Pt p = (*i)->get_vertice(1)->get_coord() + j* n; draw_segment_bis(res, p, (*i)->get_vertice(2)->get_coord(), max); } } return res; }
bool Seaweed::collisionParticleParticle(Particle *p1, Particle *p2) { // particle-particle distance // normal vector between the two Vec u = p1->getPosition() - p2->getPosition(); // norm of the vector double penetration = u.normalize(); // take into account the radius of both particles, account for potentially different radius penetration -= (p1->getRadius() + p2->getRadius()) ; if (penetration >= 0) return false; // penetration velocity double vPen = ( ( p1->getVelocity() * u) - ( p2->getVelocity() * u) ); // Reciprocity of the movement, move toward each other p1->incrPosition(-penetration * u); p2->incrPosition(penetration * u); p1->incrVelocity(-(1 + rebound) * vPen * u * p1->getMass()/(p1->getMass() + p2->getMass())); // reaction is pondered p2->incrVelocity((1 + rebound) * vPen * u * p2->getMass()/(p1->getMass() + p2->getMass())); return true; }
/** Phong lighting model ** @param pt intersection point ** @param n normal of pt ** @param light pointer to the light source ** @param obj pointer to the object ** @param ray ray ** @return color calculated from local shading using phong model **/ Vec phongModel(Vec pt, Vec n, Light* light, Shape* obj, Ray ray) { float t; Vec v = ray.getOrig() - pt; v = v.normalize(); // vector to viewer Vec l = light->pos - pt; float dis = l.mag(); // distance to light source l = l.normalize(); // vector to light source Vec ir = n * (2 * n.dot(l)) - l; ir = ir.normalize(); // vector of ideal reflector Vec intensity = light->intensity; // light intensity Ray shadowRay(pt, l, 0, 9999, ShadowRay); // shadow ray to the light source float f = light->attenFac(dis); // attentuation factor Pigment p = obj->getPigment(); Vec obj_color; // object color float scalar; int tmp; if (p.type == SOLID) { obj_color = p.c1; } else if (p.type == CHECKER) { scalar = p.width; tmp = (int)(pt.x/scalar) + (int)(pt.y/scalar) + (int)(pt.z/scalar); if (tmp % 2 == 0) obj_color = p.c1; else obj_color = p.c2; } else if (p.type == TEXTURE) { if (obj->getType() == sphere) obj_color = sphereMapping(pt, n, p); } // get the surface parameters SurFinish appearance = obj->getSurFin(); float Ka = appearance.ambient; // ambient coefficient float Kd = appearance.diffuse; // diffuse coefficient float Ks = appearance.specular; // specular coefficient float shininess = appearance.shininess; // for each object in the scene, see if is blocks the light if (light->type != ambient) { for (ShapeIter its = scene.shapes.begin(); its != scene.shapes.end(); its++) { if ((*its) == obj) continue; if ((*its)->getType() == sphere) { Sphere *shape = dynamic_cast<Sphere*>(*its); if (shape->intersect(shadowRay, t) && t < dis) return black; } else if((*its)->getType() == polyhedron){ Polyhedron *shape = dynamic_cast<Polyhedron*>(*its); if (shape->intersect(shadowRay, t) && t < dis) { return black; } } else if((*its)->getType() == triangleMesh){ TriangleMesh *shape = dynamic_cast<TriangleMesh*>(*its); if (shape->intersect(shadowRay, t) && shadowRay.calcDest(t).mag() < dis) return black; } } } Vec diffuse(0.0, 0.0, 0.0); Vec specular(0.0, 0.0, 0.0); // if the light is casted from front if (n.dot(l) > 0) { diffuse = intensity * (Kd * n.dot(l) * f); specular = white * (Ks * pow(v.dot(ir),shininess) * f); // update light color intensity.x = (light->type != ambient) ? diffuse.x * obj_color.x + specular.x : obj_color.x * Ka; intensity.y = (light->type != ambient) ? diffuse.y * obj_color.y + specular.y : obj_color.y * Ka; intensity.z = (light->type != ambient) ? diffuse.z * obj_color.z + specular.z : obj_color.z * Ka; } // if the light is casted from behind else { intensity.x = (light->type != ambient) ? black.x : obj_color.x * Ka; intensity.y = (light->type != ambient) ? black.y : obj_color.y * Ka; intensity.z = (light->type != ambient) ? black.z : obj_color.z * Ka; } return intensity; }
Vec Sphere::getNormal(const Vec & point) const { Vec ret = point - center; ret.normalize(); return ret; }
void NetworkObject::predrawVertices(QGLViewer *viewer, double *Xform, Vec pn, QList<Vec> clipPos, QList<Vec> clipNormal, QList<CropObject> crops) { Vec bmin, bmax; Global::bounds(bmin, bmax); // QMessageBox::information(0, "", QString("%1 %2 %3\n%4 %5 %6").\ // arg(bmin.x).arg(bmin.y).arg(bmin.z).\ // arg(bmax.x).arg(bmax.y).arg(bmax.z)); m_Vovertices.resize(m_vertexCenters.count()); m_Vocolor.resize(m_vertexCenters.count()); QVector<float> rad; rad.resize(m_vertexCenters.count()); int stopsCount = m_resampledVstops.count()-1; float aint = (m_userVminmax[m_Vatt].second-m_userVminmax[m_Vatt].first); if (aint <= 0.0001) aint = 1; QString txt; int nv=0; for(int i=0; i<m_vertexCenters.count(); i++) { bool ok = true; if (m_vertexAttribute[m_Vatt].second[i] < m_userVminmax[m_Vatt].first || m_vertexAttribute[m_Vatt].second[i] > m_userVminmax[m_Vatt].second) ok = false; if (ok) { for(int c=0; c<clipPos.count(); c++) { if ((m_vertexCenters[i]-clipPos[c])*clipNormal[c] > 0) { ok = false; break; } } if (ok) { for(int ci=0; ci<crops.count(); ci++) { ok &= crops[ci].checkCropped(m_vertexCenters[i]); if (!ok) break; } } if (ok) { if (m_vertexCenters[i].x >= bmin.x && m_vertexCenters[i].y >= bmin.y && m_vertexCenters[i].z >= bmin.z && m_vertexCenters[i].x <= bmax.x && m_vertexCenters[i].y <= bmax.y && m_vertexCenters[i].z <= bmax.z) { m_Vovertices[nv] = Matrix::xformVec(Xform, m_vertexCenters[i]); //rad[nv] = 1.5*m_vertexAttribute[m_vertexRadiusAttribute].second[i]; rad[nv] = m_scaleV * m_vertexAttribute[m_vertexRadiusAttribute].second[i]; float stp = (m_vertexAttribute[m_Vatt].second[i] - m_userVminmax[m_Vatt].first) / aint; QColor col = m_resampledVstops[stp*stopsCount].second; float r = col.red()/255.0; float g = col.green()/255.0; float b = col.blue()/255.0; m_Vocolor[nv] = Vec(r,g,b); nv++; } } } } m_Vovertices.resize(nv+1); m_VtexValues.resize(m_Vovertices.count()); for(int i=0; i<m_Vovertices.count(); i++) m_VtexValues[i] = pn*m_Vovertices[i]; Vec p = pn^viewer->camera()->upVector(); Vec q = pn^p; p.normalize(); q.normalize(); m_Vvertices.resize(4*m_Vovertices.count()); for(int i=0; i<m_Vovertices.count(); i++) { m_Vvertices[4*i+0] = m_Vovertices[i]-rad[i]*p-rad[i]*q; m_Vvertices[4*i+1] = m_Vovertices[i]-rad[i]*p+rad[i]*q; m_Vvertices[4*i+2] = m_Vovertices[i]+rad[i]*p+rad[i]*q; m_Vvertices[4*i+3] = m_Vovertices[i]+rad[i]*p-rad[i]*q; } }
void Bond::drawBallsAndSticks(bool selected) { GLfloat radius(s_radiusBallsAndSticks*m_scale); if (selected) { radius += Primitive::s_selectOffset; glColor4fv(Primitive::s_selectColor); }else { glColor4fv(s_defaultColor); } Vec a(m_begin->displacedPosition()); Vec b(m_end ->displacedPosition()); Vec normal = cross(s_cameraPosition-a, s_cameraPosition-b); normal.normalize(); GLfloat length((a-b).norm()); Frame frame(m_frame); GLUquadric* quad = gluNewQuadric(); switch (m_order) { case 1: { glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); } break; case 2: { normal *= 0.08; // Governs the offset for the bond lines radius *= 0.7; // Make the bonds a bit thinner frame.translate(-normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); frame.translate(2.0*normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); } break; case 3: { normal *= 0.11; // Governs the offset for the bond lines radius *= 0.45; // Make the bonds a bit thinner frame.translate(-normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); frame.translate(normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); frame.translate(normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); } break; case 4: { normal *= 0.11; // Governs the offset for the bond lines radius *= 0.40; // Make the bonds a bit thinner frame.translate(-1.5*normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); frame.translate(normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); frame.translate(normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); frame.translate(normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); } break; case 5: { // Aromatic normal *= 0.08; // Governs the offset for the bond lines frame.translate(-normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); radius *= 0.5; // Make the second bond a bit thinner frame.translate(2.0*normal); glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); } break; default: { radius *= 2; // Fat bond indicates we don't know what we are doing glPushMatrix(); glMultMatrixd(frame.matrix()); gluCylinder(quad, radius, radius, length, Primitive::s_resolution, 1); glPopMatrix(); } break; } gluDeleteQuadric(quad); }
void Bond::drawWireFrame(bool selected) { GLfloat radius(s_radiusWireFrame*m_scale); Vec a(m_begin->displacedPosition()); Vec b(m_end ->displacedPosition()); GLfloat length((a-b).norm()); glPushMatrix(); glMultMatrixd(m_frame.matrix()); GLboolean lightingEnabled(glIsEnabled(GL_LIGHTING)); glDisable(GL_LIGHTING); if (!selected) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); } Vec normal = cross(s_cameraPosition-a, s_cameraPosition-b); normal.normalize(); a.setValue(0.0, 0.0, 0.0); b.setValue(0.0, 0.0, length); Vec m(0.5*(a+b)); // bond midpoint if (selected) { glColor4fv(Primitive::s_selectColor); radius += Primitive::s_selectOffsetWireFrame; glLineWidth(radius); glBegin(GL_LINES); glVertex3f(a.x, a.y, a.z); glVertex3f(b.x, b.y, b.z); glEnd(); }else { glLineWidth(radius); switch (m_order) { case 2: normal *= 0.03; // Governs the offset for the bond lines glBegin(GL_LINES); a -= normal; b -= normal; m -= normal; glColor4fv(m_begin->m_color); glVertex3f(a.x, a.y, a.z); glVertex3f(m.x, m.y, m.z); glColor4fv(m_end->m_color); glVertex3f(m.x, m.y, m.z); glVertex3f(b.x, b.y, b.z); a += 2.0*normal; b += 2.0*normal; m += 2.0*normal; glColor4fv(m_begin->m_color); glVertex3f(a.x, a.y, a.z); glVertex3f(m.x, m.y, m.z); glColor4fv(m_end->m_color); glVertex3f(m.x, m.y, m.z); glVertex3f(b.x, b.y, b.z); glEnd(); break; case 3: normal *= 0.04; // Governs the offset for the bond lines glBegin(GL_LINES); a -= normal; b -= normal; m -= normal; glColor4fv(m_begin->m_color); glVertex3f(a.x, a.y, a.z); glVertex3f(m.x, m.y, m.z); glColor4fv(m_end->m_color); glVertex3f(m.x, m.y, m.z); glVertex3f(b.x, b.y, b.z); a += normal; b += normal; m += normal; glColor4fv(m_begin->m_color); glVertex3f(a.x, a.y, a.z); glVertex3f(m.x, m.y, m.z); glColor4fv(m_end->m_color); glVertex3f(m.x, m.y, m.z); glVertex3f(b.x, b.y, b.z); a += normal; b += normal; m += normal; glColor4fv(m_begin->m_color); glVertex3f(a.x, a.y, a.z); glVertex3f(m.x, m.y, m.z); glColor4fv(m_end->m_color); glVertex3f(m.x, m.y, m.z); glVertex3f(b.x, b.y, b.z); glEnd(); break; default: glBegin(GL_LINES); glColor4fv(m_begin->m_color); glVertex3f(a.x, a.y, a.z); glVertex3f(m.x, m.y, m.z); glColor4fv(m_end->m_color); glVertex3f(m.x, m.y, m.z); glVertex3f(b.x, b.y, b.z); glEnd(); break; } } if (!selected) { glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } if (lightingEnabled) glEnable(GL_LIGHTING); glPopMatrix(); }
void NetworkObject::predrawEdges(QGLViewer *viewer, double *Xform, Vec pn, QList<Vec> clipPos, QList<Vec> clipNormal, QList<CropObject> crops) { Vec bmin, bmax; Global::bounds(bmin, bmax); m_Eovertices.resize(2*m_edgeNeighbours.count()); m_Eocolor.resize(m_edgeNeighbours.count()); QVector<float> rad; rad.resize(m_edgeNeighbours.count()); int stopsCount = m_resampledEstops.count()-1; float aint = (m_userEminmax[m_Eatt].second-m_userEminmax[m_Eatt].first); if (aint <= 0.0001) aint = 1; int nv = 0; for(int i=0; i<m_edgeNeighbours.count(); i++) { bool ok = true; if (m_edgeAttribute[m_Eatt].second[i] < m_userEminmax[m_Eatt].first || m_edgeAttribute[m_Eatt].second[i] > m_userEminmax[m_Eatt].second) ok = false; if (ok) { int a = m_edgeNeighbours[i].first; int b = m_edgeNeighbours[i].second; Vec pa = m_vertexCenters[a]; Vec pb = m_vertexCenters[b]; for(int c=0; c<clipPos.count(); c++) { if ((pa-clipPos[c])*clipNormal[c] > 0 || (pb-clipPos[c])*clipNormal[c] > 0) { ok = false; break; } } if (ok) { for(int ci=0; ci<crops.count(); ci++) { ok &= crops[ci].checkCropped(pa); if (!ok) break; ok &= crops[ci].checkCropped(pb); if (!ok) break; } } if (ok) { pa = Matrix::xformVec(Xform, pa); pb = Matrix::xformVec(Xform, pb); if (m_vertexCenters[a].x >= bmin.x && m_vertexCenters[a].y >= bmin.y && m_vertexCenters[a].z >= bmin.z && m_vertexCenters[a].x <= bmax.x && m_vertexCenters[a].y <= bmax.y && m_vertexCenters[a].z <= bmax.z && m_vertexCenters[b].x >= bmin.x && m_vertexCenters[b].y >= bmin.y && m_vertexCenters[b].z >= bmin.z && m_vertexCenters[b].x <= bmax.x && m_vertexCenters[b].y <= bmax.y && m_vertexCenters[b].z <= bmax.z) { if (m_Vopacity > 0.5) { Vec p = pb-pa; p.normalize(); pa = pa + p*m_vertexAttribute[m_vertexRadiusAttribute].second[a]; pb = pb - p*m_vertexAttribute[m_vertexRadiusAttribute].second[b]; } m_Eovertices[2*nv] = pa; m_Eovertices[2*nv+1] = pb; //rad[nv] = m_edgeAttribute[m_edgeRadiusAttribute].second[i]; rad[nv] = m_scaleE * m_edgeAttribute[m_edgeRadiusAttribute].second[i]; float stp = (m_edgeAttribute[m_Eatt].second[i] - m_userEminmax[m_Eatt].first) / aint; QColor col = m_resampledEstops[stp*stopsCount].second; float r = col.red()/255.0; float g = col.green()/255.0; float b = col.blue()/255.0; m_Eocolor[nv] = Vec(r,g,b); nv ++; } } } } m_Eovertices.resize(2*(nv+1)); m_EtexValues.resize(m_Eovertices.count()); for(int i=0; i<m_Eovertices.count(); i++) m_EtexValues[i] = pn*m_Eovertices[i]; Vec p = pn^viewer->camera()->upVector(); Vec q = pn^p; p.normalize(); q.normalize(); m_Evertices.resize(2*m_Eovertices.count()); for(int i=0; i<m_Eovertices.count()/2; i++) { Vec pa = m_Eovertices[2*i]; Vec pb = m_Eovertices[2*i+1]; Vec p = pn^(pa-pb); p.normalize(); p *= rad[i]; m_Evertices[4*i+0] = pa-p; m_Evertices[4*i+1] = pb-p; m_Evertices[4*i+2] = pb+p; m_Evertices[4*i+3] = pa+p; } }
void ClipGrabber::mouseMoveEvent(QMouseEvent* const event, Camera* const camera) { if (!m_pressed) return; QPoint delta = event->pos() - m_prevPos; Vec voxelScaling = Global::voxelScaling(); Vec tang = m_tang; Vec xaxis = m_xaxis; Vec yaxis = m_yaxis; tang = Matrix::rotateVec(m_xform, tang); xaxis = Matrix::rotateVec(m_xform, xaxis); yaxis = Matrix::rotateVec(m_xform, yaxis); if (event->buttons() != Qt::LeftButton) { tang = VECDIVIDE(tang, voxelScaling); xaxis = VECDIVIDE(xaxis, voxelScaling); yaxis = VECDIVIDE(yaxis, voxelScaling); Vec trans(delta.x(), -delta.y(), 0.0f); // Scale to fit the screen mouse displacement trans *= 2.0 * tan(camera->fieldOfView()/2.0) * fabs((camera->frame()->coordinatesOf(Vec(0,0,0))).z) / camera->screenHeight(); // Transform to world coordinate system. trans = camera->frame()->orientation().rotate(trans); Vec voxelScaling = Global::voxelScaling(); trans = VECDIVIDE(trans, voxelScaling); if (event->modifiers() & Qt::ControlModifier || event->modifiers() & Qt::MetaModifier) { if (moveAxis() < MoveY0) { float vx = trans*m_xaxis; if (moveAxis() == MoveX0) setScale1(scale1() + 0.05*vx); else setScale1(scale1() - 0.05*vx); } else if (moveAxis() < MoveZ) { float vy = trans*m_yaxis; if (moveAxis() == MoveY0) setScale2(scale2() + 0.05*vy); else setScale2(scale2() - 0.05*vy); } } else { if (moveAxis() < MoveY0) { float vx = trans*xaxis; trans = vx*xaxis; } else if (moveAxis() < MoveZ) { float vy = trans*yaxis; trans = vy*yaxis; } else if (moveAxis() == MoveZ) { float vz = trans*tang; trans = vz*tang; } translate(trans); } } else { Vec axis; if (moveAxis() < MoveY0) axis = xaxis; else if (moveAxis() < MoveZ) axis = yaxis; else if (moveAxis() == MoveZ) axis = tang; Vec voxelScaling = Global::voxelScaling(); Vec pos = VECPRODUCT(position(), voxelScaling); pos = Matrix::xformVec(m_xform, pos); float r = size(); Vec trans(delta.x(), -delta.y(), 0.0f); Vec p0 = camera->projectedCoordinatesOf(pos); p0 = Vec(p0.x, p0.y, 0); Vec c0 = pos + r*axis; c0 = camera->projectedCoordinatesOf(c0); c0 = Vec(c0.x, c0.y, 0); Vec perp = c0-p0; perp = Vec(-perp.y, perp.x, 0); perp.normalize(); float angle = perp * trans; rotate(axis, angle); } m_prevPos = event->pos(); }
void GiLightObject::computeTangents() { m_xaxis.clear(); m_yaxis.clear(); m_tgP.clear(); int nkf = m_points.count(); if (nkf < 2) { m_xaxis << Vec(1,0,0); m_yaxis << Vec(0,1,0); m_tgP << Vec(0,0,1); return; } Vec pxaxis = Vec(1,0,0); Vec ptang = Vec(0,0,1); for(int kf=0; kf<nkf; kf++) { Vec prevP, nextP; if (kf == 0) { prevP = m_points[kf]; } else prevP = m_points[kf-1]; if (kf == nkf-1) { nextP = m_points[kf]; } else nextP = m_points[kf+1]; Vec tgP = 0.5*(nextP - prevP); m_tgP.append(tgP); //------------------- tgP.normalize(); Vec xaxis, yaxis; Vec axis; float angle; StaticFunctions::getRotationBetweenVectors(ptang, tgP, axis, angle); if (qAbs(angle) > 0.0 && qAbs(angle) < 3.1415) { Quaternion q(axis, angle); xaxis = q.rotate(pxaxis); } else xaxis = pxaxis; yaxis = tgP^xaxis; m_xaxis.append(xaxis); m_yaxis.append(yaxis); pxaxis = xaxis; ptang = tgP; //------------------- } }