/////////////////////////////////////////////////////////////////////// // Class : CXform // Method : translate // Description : Append a translation. Note that the last // specified transformation is applied first // Return Value : - // Comments : void CXform::translate(float dx,float dy,float dz) { matrix tmp,tmp2; translatem(tmp,-dx,-dy,-dz); mulmm(tmp2,tmp,to); movmm(to,tmp2); translatem(tmp,dx,dy,dz); mulmm(tmp2,from,tmp); movmm(from,tmp2); }
/////////////////////////////////////////////////////////////////////// // Class : CXform // Method : skew // Description : Append a skew // Return Value : - // Comments : void CXform::skew(float angle,float dx1,float dy1,float dz1,float dx2,float dy2,float dz2) { matrix tmp,tmp2; const float r = (float) radians(angle); skewm(tmp,-r,dx1,dy1,dz1,dx2,dy2,dz2); mulmm(tmp2,tmp,to); movmm(to,tmp2); skewm(tmp,r,dx1,dy1,dz1,dx2,dy2,dz2); mulmm(tmp2,from,tmp); movmm(from,tmp2); }
/////////////////////////////////////////////////////////////////////// // Class : CXform // Method : rotate // Description : Append a rotation // Return Value : - // Comments : void CXform::rotate(float angle,float x,float y,float z) { matrix tmp,tmp2; const float r = (float) radians(angle); rotatem(tmp,-x,-y,-z,r); mulmm(tmp2,tmp,to); movmm(to,tmp2); rotatem(tmp,x,y,z,r); mulmm(tmp2,from,tmp); movmm(from,tmp2); }
/////////////////////////////////////////////////////////////////////// // Class : CXform // Method : concat // Description : Concetenate another transformation (This // transformation will be applied first) // Return Value : - // Comments : void CXform::concat(CXform *x) { matrix tmp; if (x->next != NULL) { if (next == NULL) next = new CXform(this); next->concat(x->next); } mulmm(tmp,x->to,to); movmm(to,tmp); mulmm(tmp,from,x->from); movmm(from,tmp); }
/////////////////////////////////////////////////////////////////////// // Class : CXform // Method : scale // Description : Append a scale // Return Value : - // Comments : void CXform::scale(float sx,float sy,float sz) { matrix tmp,tmp2; if ((sx == 0) || (sy == 0) || (sz == 0)) error(CODE_MATH,"Singular scale (%f %f %f) (ignored)\n",sx,sy,sz); else { scalem(tmp,1/sx,1/sy,1/sz); mulmm(tmp2,tmp,to); movmm(to,tmp2); scalem(tmp,sx,sy,sz); mulmm(tmp2,from,tmp); movmm(from,tmp2); } }
static void compute_transfer_matrix(mat4x4 * M, struct vec3 * pvecs, struct vec3 * tvecs) { /* T: texture coords */ /* P: physical coords */ /* M: result matrix */ /* M * T = P */ /* M = P * T^(-1) */ mat4x4 T, P; _matrix_load_identity(&T); _matrix_load_identity(&P); T.m[0][0] = tvecs[0].x; T.m[0][1] = tvecs[0].y; T.m[0][2] = 1.0; T.m[0][3] = 0.0; T.m[1][0] = tvecs[1].x; T.m[1][1] = tvecs[1].y; T.m[1][2] = 1.0; T.m[1][3] = 0.0; T.m[2][0] = tvecs[2].x; T.m[2][1] = tvecs[2].y; T.m[2][2] = 1.0; T.m[2][3] = 0.0; P.m[0][0] = pvecs[0].x; P.m[0][1] = pvecs[0].y; P.m[0][2] = pvecs[0].z; P.m[0][3] = 0.0; P.m[1][0] = pvecs[1].x; P.m[1][1] = pvecs[1].y; P.m[1][2] = pvecs[1].z; P.m[1][3] = 0.0; P.m[2][0] = pvecs[2].x; P.m[2][1] = pvecs[2].y; P.m[2][2] = pvecs[2].z; P.m[2][3] = 0.0; invert_matrix(&T, &T); mulmm(M, &P, &T); return; }
/////////////////////////////////////////////////////////////////////// // Class : CBSplinePatchGrid // Method : CBSplinePatchGrid // Description : /// \brief Ctor // Return Value : - // Comments : CBSplinePatchGrid::CBSplinePatchGrid(CAttributes *a,CXform *x,CVertexData *var,CParameter *p,int nu,int nv,float uOrg,float vOrg,float uMult,float vMult,float *ve) : CSurface(a,x) { atomicIncrement(&stats.numGprims); variables = var; variables->attach(); parameters = p; uVertices = nu; vVertices = nv; this->uOrg = uOrg; this->vOrg = vOrg; this->uMult = uMult; this->vMult = vMult; const int numVertices = (nu*nv); int i,j,k; matrix ut; matrix bsplinebasis; matrix geometryU,geometryV; matrix tmp; const int upatches = uVertices - 3; const int vpatches = vVertices - 3; initv(bmin,C_INFINITY,C_INFINITY,C_INFINITY); initv(bmax,-C_INFINITY,-C_INFINITY,-C_INFINITY); // Note that u basis and v basis are swapped to take the transpose into account done during the precomputation // Note also that we could use the B-spline basis to bound the curve, but Bezier bound is tighter for (i=0;i<4;i++) for (j=0;j<4;j++) bsplinebasis[element(i,j)] = RiBSplineBasis[j][i]; transposem(ut,bsplinebasis); mulmm(geometryV,invBezier,ut); mulmm(geometryU,bsplinebasis,invBezier); // alloc off upatches*vpatches*16*vertexSize worth of data const int vertexSize = var->vertexSize; const int vs = (variables->moving ? vertexSize*2 : vertexSize); vertex = new float[vs*16*upatches*vpatches]; for (i=0;i<vpatches;i++) { for (j=0;j<upatches;j++) { int r,c; float *patchData = vertex + (i*upatches + j)*16*vertexSize; // Fill in the geometry matrices for (r=0;r<4;r++) { int y = (r + i) % vVertices; for (c=0;c<4;c++) { int x = (c + j) % uVertices; const float *d = ve + (y*uVertices+x)*vs; for (k=0;k<vertexSize;k++) { patchData[16*k + element(r,c)] = *d++; } } } // add to bounds makeCubicBound(bmin,bmax,patchData+0*16,patchData+1*16,patchData+2*16); // precompute B*G*B' and stash it for (k=0;k<vertexSize;k++) { mulmm(tmp,ut,patchData); mulmm(patchData,tmp,bsplinebasis); patchData += 16; } // do the same for moving points if (variables->moving) { patchData = vertex + (upatches*vpatches + i*upatches + j)*16*vertexSize; for (r=0;r<4;r++) { int y = (r + i) % vVertices; for (c=0;c<4;c++) { int x = (c + j) % uVertices; const float *d = ve + vertexSize + (y*uVertices+x)*vs; for (k=0;k<vertexSize;k++) { patchData[16*k + element(r,c)] = *d++; } } } // add to bounds makeCubicBound(bmin,bmax,patchData+0*16,patchData+1*16,patchData+2*16); // precompute B*G*B' and stash it for (k=0;k<vertexSize;k++) { mulmm(tmp,ut,patchData); mulmm(patchData,tmp,bsplinebasis); patchData += 16; } } } } makeBound(bmin,bmax); }