//=================================================== mouse2plane //=============================================================== void TFWidgetRen::mouse2plane(int x, int y) { // assume we are always aligned with z axis // should be based on up vector and (at-eye)xup vector!!!!! float fx = 1 - (float)x/(float)gluvv.win.width; float fy = (float)(gluvv.win.height - y)/(float)gluvv.win.height; float vdir[3]; subV3(vdir, gluvv.env.at, gluvv.env.eye); normalizeV3(vdir); scaleV3(gluvv.env.clip[0], vdir); float fcp[3]; //position of front clipping plane addV3(fcp, gluvv.env.eye, vdir); float cpnt[3];//clip plane point (projecton of screen point on clip plane) cpnt[0] = ((fcp[0] + gluvv.env.frustum[0]) + (gluvv.env.frustum[1] - gluvv.env.frustum[0]) * fx); cpnt[1] = ((fcp[1] + gluvv.env.frustum[2]) + (gluvv.env.frustum[3] - gluvv.env.frustum[2]) * fy); cpnt[2] = fcp[2]; //remember, assume z aligned view direction float ep[3]; //eye - pos subV3(ep, gluvv.env.eye, pos); float me[3]; //eye - clipplane point subV3(me, gluvv.env.eye, cpnt); float dir[3] = {0,0,-1}; float t = dotV3(dir, ep)/dotV3(dir, me); negateV3(me); scaleV3(t,me); addV3(mousepnt, me, gluvv.env.eye); }
void uniqueMap(obj* object) { int i, j, k; int vIndices[3], tIndices[3]; for(i = 0; i < object->faceCount; ++i) { for(j = 0; j < 3; ++j) { vIndices[j] = object->faces[i][j][0] - 1; tIndices[j] = object->faces[i][j][1] - 1; } for(j = 0; j < 3; ++j) { vec3 V[3]; vec2 T[3]; for(k = 0; k < 3; ++k) { V[k] = object->vertices[vIndices[(j+k)%3]]; T[k] = object->textures[tIndices[(j+k)%3]]; } vec3 edge1 = subV3(V[1], V[0]); vec3 edge2 = subV3(V[2], V[0]); vec2 deltaUV1 = subV2(T[1], T[0]); vec2 deltaUV2 = subV2(T[2], T[0]); GLfloat f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); vec3 tangent; tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); tangent.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); tangent = unit(tangent); vec3 bitangent; bitangent.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); bitangent.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); bitangent.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); bitangent = unit(bitangent); object->tangents[vIndices[j]] = addV3(object->tangents[vIndices[j]], tangent); object->bitangents[vIndices[j]] = addV3(object->bitangents[vIndices[j]], bitangent); } for(j = 0; j < 3; ++j) ++object->shared[vIndices[j]]; } for(i = 0; i < object->vertexCount; ++i) { object->tangents[i] = unit(scale(object->tangents[i], 1.0f / object->shared[i])); object->bitangents[i] = unit(scale(object->bitangents[i], 1.0f / object->shared[i])); } }
//========================================================== move //=============================================================== int TFWidgetRen::move(int x, int y) { if(pickedObj == LEVWIDGNAME){ if(pickedTri == brush->id) return brush->move(x,y); else return tris->move(x, y); } float sdx = (float)(x - lastwinpos[0])/(float)gluvv.win.width; float sdy = (float)(y - lastwinpos[1])/(float)gluvv.win.height; //had to change this should be smarter float d[3]; subV3(d, pos, gluvv.env.eye); //float dist = normV3(d); float dist = pos[2] - gluvv.env.eye[2]; float dx = sdx * (gluvv.env.frustum[1]-gluvv.env.frustum[0]) * dist/gluvv.env.clip[0]; float dy = sdy * (gluvv.env.frustum[3]-gluvv.env.frustum[2]) * dist/gluvv.env.clip[0]; switch(gluvv.mouse.state){//////////////////////////////////// case GLUT_DOWN: switch(gluvv.mouse.button){/////////////////////// case GLUT_LEFT_BUTTON: switch(pickedObj){/////////////////// case bbar: case tbar: case lbar: case rbar: screenpos[0] -= sdx; screenpos[1] -= sdy; gluvv.rinfo.sampleRate = gluvv.rinfo.interactSamp; glutSetWindowTitle("Transfer Function Widget: MOVE"); glutPostRedisplay(); break; case blball: screenpos[0] -= sdx; screenpos[1] -= sdy; screenwidth -= sdx; screenheight += sdy; gluvv.rinfo.sampleRate = gluvv.rinfo.interactSamp; glutSetWindowTitle("Transfer Function Widget: RESIZE"); glutPostRedisplay(); break; case brball: screenpos[1] -= sdy; screenwidth += sdx; screenheight += sdy; gluvv.rinfo.sampleRate = gluvv.rinfo.interactSamp; glutSetWindowTitle("Transfer Function Widget: RESIZE"); glutPostRedisplay(); break; case tlball: screenpos[0] -= sdx; screenwidth -= sdx; screenheight -= sdy; gluvv.rinfo.sampleRate = gluvv.rinfo.interactSamp; glutSetWindowTitle("Transfer Function Widget: RESIZE"); glutPostRedisplay(); break; case trball: screenwidth += sdx; screenheight -= sdy; gluvv.rinfo.sampleRate = gluvv.rinfo.interactSamp; glutSetWindowTitle("Transfer Function Widget: RESIZE"); glutPostRedisplay(); break; case beslider: if(pickedTri){ LevWidget *tt; if(tt = tris->get(pickedTri)){ float slider = tt->getBE(); slider += dx/width; tt->setBE(slider); glutSetWindowTitle("Transfer Function Widget: Boundary Emphasis"); gluvv.rinfo.sampleRate = gluvv.rinfo.interactSamp; glutPostRedisplay(); gluvv.tf.loadme = 1; } } break; }/////////////////////////////////// break; case GLUT_MIDDLE_BUTTON: switch(pickedObj){/////////////////// case bbar: case tbar: case lbar: case rbar: pos[0] -= dx; pos[2] -= dy; gluvv.rinfo.sampleRate = gluvv.rinfo.interactSamp; glutSetWindowTitle("Transfer Function Widget: MOVE"); glutPostRedisplay(); break; } break; case GLUT_RIGHT_BUTTON: break; }/////////////////////////////////////////////// break; case GLUT_UP: break; }//////////////////////////////////////////////////////////// lastwinpos[0] = x; lastwinpos[1] = y; return 1; }
//=================================================== TFWidgetRen //=============================================================== TFWidgetRen::TFWidgetRen(gluvvGlobal *gl) { pos[0] = 0; pos[1] = 0; pos[2] = -4; screenwidth = .9; screenheight = .2; screenpos[0] = .45; screenpos[1] = -.46; mode = colorBlend; float d[3]; subV3(d, pos, gluvv.env.eye); float dist = normV3(d); width = ((gluvv.env.frustum[1]-gluvv.env.frustum[0]) * dist/gluvv.env.clip[0]) * screenwidth; height = ((gluvv.env.frustum[3]-gluvv.env.frustum[2]) * dist/gluvv.env.clip[0]) * screenheight; pos[0] = ((gluvv.env.frustum[1]-gluvv.env.frustum[0]) * dist/gluvv.env.clip[0]) * screenpos[0]; pos[1] = ((gluvv.env.frustum[1]-gluvv.env.frustum[0]) * dist/gluvv.env.clip[0]) * screenpos[1]; screenbar = .01; screenball = screenbar * 1.5; barRad = ((gluvv.env.frustum[1]-gluvv.env.frustum[0]) * dist/gluvv.env.clip[0]) * screenbar; ballRad = ((gluvv.env.frustum[1]-gluvv.env.frustum[0]) * dist/gluvv.env.clip[0]) * screenball; //-------- Levoy triangles ----------- tris = new LevWidget(&gluvv); tris->setWH(width-ballRad*2, height-ballRad*2); float b[2] = {.5,0}; float l[2]={.3,.7}; float r[2] = {.7,.7}; tris->setPos(b,l,r); tris->setBallBar(ballRad/2.0, barRad/2.0); tris->setDepth(pos[2]); tris->squareType(); tris->on = 0; //turn root triangle off brush= new LevWidget(&gluvv); brush->setWH(width-ballRad*2, height-ballRad*2); brush->setPos(b,l,r); brush->setBallBar(ballRad/2.0, barRad/2.0); brush->setDepth(pos[2]); brush->setAlpha(.2); brush->squareType(); brush->on = 1; //turn paint brush on brush->drawOn = 0; //but dont actualy draw the widget widgetInit(); transparent(); gluvv.tf.loadme = 1; gluvv.tf.paintme = 0; //make space for pixel texture (memory copy) gluvv.tf.ptexsz[0] = 256;//value gluvv.tf.ptexsz[1] = 256;//grad gluvv.tf.ptexsz[2] = 4; //hess, four panes gluvv.tf.numelts = 4; //rgba glGenTextures(1, &gluvv.tf.ptextex); //drawable texture //glGenTextures(1, &gluvv.tf.ptexname); //actual pixel texture //cerr << "the pixel texture name " << gluvv.tf.ptexname << endl; gluvv.tf.qnptexname = 0; if(gluvv.tf.ptex) delete[] gluvv.tf.ptex; gluvv.tf.ptex = new unsigned char[(gluvv.tf.ptexsz[0]* gluvv.tf.ptexsz[1]* gluvv.tf.ptexsz[2]* gluvv.tf.numelts)]; gluvv.tf.paintex = new unsigned char[(gluvv.tf.ptexsz[0]* gluvv.tf.ptexsz[1]* gluvv.tf.ptexsz[2]* gluvv.tf.numelts)]; gluvv.tf.shadePtex = new unsigned char[(gluvv.tf.ptexsz[0]* gluvv.tf.ptexsz[1]* gluvv.tf.ptexsz[2]* gluvv.tf.numelts)]; clearPaintex(); gluvv.tf.ptex[0 + 0] = 0; gluvv.tf.ptex[0 + 1] = 0; gluvv.tf.ptex[0 + 2] = 0; gluvv.tf.ptex[0 + 3] = 0; }