static void make_transform_matrix( int transform_order, int rotate_order, double tx, double ty, double tz, double rx, double ry, double rz, double sx, double sy, double sz, double *transform) { int i; double T[16], R[16], S[16], RX[16], RY[16], RZ[16]; double *queue[3]; MatTranslate(T, tx, ty, tz); MatRotateX(RX, rx); MatRotateY(RY, ry); MatRotateZ(RZ, rz); MatScale(S, sx, sy, sz); switch (rotate_order) { case ORDER_XYZ: VEC3_SET(queue, RX, RY, RZ); break; case ORDER_XZY: VEC3_SET(queue, RX, RZ, RY); break; case ORDER_YXZ: VEC3_SET(queue, RY, RX, RZ); break; case ORDER_YZX: VEC3_SET(queue, RY, RZ, RX); break; case ORDER_ZXY: VEC3_SET(queue, RZ, RX, RY); break; case ORDER_ZYX: VEC3_SET(queue, RZ, RY, RX); break; default: assert(!"invalid rotate order"); break; } MatIdentity(R); for (i = 0; i < 3; i++) MatMultiply(R, queue[i], R); switch (transform_order) { case ORDER_SRT: VEC3_SET(queue, S, R, T); break; case ORDER_STR: VEC3_SET(queue, S, T, R); break; case ORDER_RST: VEC3_SET(queue, R, S, T); break; case ORDER_RTS: VEC3_SET(queue, R, T, S); break; case ORDER_TRS: VEC3_SET(queue, T, R, S); break; case ORDER_TSR: VEC3_SET(queue, T, S, R); break; default: assert(!"invalid transform order order"); break; } MatIdentity(transform); for (i = 0; i < 3; i++) MatMultiply(transform, queue[i], transform); }
/* *--------------------------------------------------------- * Compute a rotation matrix around an arbitrary axis * specified by 2 points p1 and p2; theta is the angle * between the two planes that share the same edge * defined by p1 and p2 *--------------------------------------------------------- */ int MxRotateAxisAlain(Point3D p1, Point3D p2, double theta, Matrix4 *TM, Matrix4 *iTM) { Point3D p; double dist, cosX, sinX, cosY, sinY; Matrix4 m1, m2, Identity; loadIdentity( &Identity ); p.x = p2.x - p1.x; p.y = p2.y - p1.y; p.z = p2.z - p1.z; if( V3Length( &p ) < 0.0 ) return(FALSE); dist = sqrt( p.y * p.y + p.z * p.z ); if(dist < DAMN_SMALL){ cosX = 1.0; sinX = 0.0; } else{ cosX = p.z / dist; sinX = -p.y / dist; } cosY = dist; sinY = -p.x; loadIdentity( TM ); TM->element[3][0] = -p1.x; TM->element[3][1] = -p1.y; TM->element[3][2] = -p1.z; MatrixCopy( TM, &m1); loadIdentity( &m2 ); m2.element[1][1] = cosX; m2.element[2][1] = sinX; m2.element[1][2] = -sinX; m2.element[2][2] = cosX; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[0][0] = cosY; m2.element[2][0] = sinY; m2.element[0][2] = -sinY; m2.element[2][2] = cosY; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); MatRotateZ( theta, &m2 ); MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[0][0] = cosY; m2.element[2][0] = -sinY; m2.element[0][2] = sinY; m2.element[2][2] = cosY; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[1][1] = cosX; m2.element[2][1] = -sinX; m2.element[1][2] = sinX; m2.element[2][2] = cosX; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[3][0] = p1.x; m2.element[3][1] = p1.y; m2.element[3][2] = p1.z; MatMul( &m1, &m2, TM ); return( MxInvert(TM, iTM) ); }
int main(int argc,char **argv) { // initialize generator InitTexgen(); // colors Pixel black,white; black.Init(0,0,0,255); white.Init(255,255,255,255); timeBeginPeriod(1); sInt startTime = timeGetTime(); for(sInt i=0;i<100;i++) { // create gradients GenTexture gradBW = LinearGradient(0xff000000,0xffffffff); GenTexture gradWB = LinearGradient(0xffffffff,0xff000000); GenTexture gradWhite = LinearGradient(0xffffffff,0xffffffff); // simple noise test texture GenTexture noise; noise.Init(256,256); noise.Noise(gradBW,2,2,6,0.5f,123,GenTexture::NoiseDirect|GenTexture::NoiseBandlimit|GenTexture::NoiseNormalize); /*// save test image if(!SaveImage(noise,"noise.tga")) { printf("Couldn't write 'noise.tga'!\n"); return 1; }*/ // 4 "random voronoi" textures with different minimum distances GenTexture voro[4]; static sInt voroIntens[4] = { 37, 42, 37, 37 }; static sInt voroCount[4] = { 90, 132, 240, 255 }; static sF32 voroDist[4] = { 0.125f, 0.063f, 0.063f, 0.063f }; for(sInt i=0;i<4;i++) { voro[i].Init(256,256); RandomVoronoi(voro[i],gradWhite,voroIntens[i],voroCount[i],voroDist[i]); } // linear combination of them LinearInput inputs[4]; for(sInt i=0;i<4;i++) { inputs[i].Tex = &voro[i]; inputs[i].Weight = 1.5f; inputs[i].UShift = 0.0f; inputs[i].VShift = 0.0f; inputs[i].FilterMode = GenTexture::WrapU|GenTexture::WrapV|GenTexture::FilterNearest; } GenTexture baseTex; baseTex.Init(256,256); baseTex.LinearCombine(black,0.0f,inputs,4); // blur it baseTex.Blur(baseTex,0.0074f,0.0074f,1,GenTexture::WrapU|GenTexture::WrapV); // add a noise layer GenTexture noiseLayer; noiseLayer.Init(256,256); noiseLayer.Noise(LinearGradient(0xff000000,0xff646464),4,4,5,0.995f,3,GenTexture::NoiseDirect|GenTexture::NoiseNormalize|GenTexture::NoiseBandlimit); baseTex.Paste(baseTex,noiseLayer,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,GenTexture::CombineAdd,0); // colorize it Colorize(baseTex,0xff747d8e,0xfff1feff); // Create transform matrix for grid pattern Matrix44 m1,m2,m3; MatTranslate(m1,-0.5f,-0.5f,0.0f); MatScale(m2,3.0f * sSQRT2F,3.0f * sSQRT2F,1.0f); MatMult(m3,m2,m1); MatRotateZ(m1,0.125f * sPI2F); MatMult(m2,m1,m3); MatTranslate(m1,0.5f,0.5f,0.0f); MatMult(m3,m1,m2); // Grid pattern GlowRect GenTexture rect1,rect1x,rect1n; rect1.Init(256,256); rect1.LinearCombine(black,1.0f,0,0); // black background rect1.GlowRect(rect1,gradWB,0.5f,0.5f,0.41f,0.0f,0.0f,0.25f,0.7805f,0.64f); rect1x.Init(256,256); rect1x.CoordMatrixTransform(rect1,m3,GenTexture::WrapU|GenTexture::WrapV|GenTexture::FilterBilinear); // Make a normalmap from it rect1n.Init(256,256); rect1n.Derive(rect1x,GenTexture::DeriveNormals,2.5f); // Apply as bump map GenTexture finalTex; Pixel amb,diff; finalTex.Init(256,256); amb.Init(0xff101010); diff.Init(0xffffffff); finalTex.Bump(baseTex,rect1n,0,0,0.0f,0.0f,0.0f,-2.518f,0.719f,-3.10f,amb,diff,sTRUE); // Second grid pattern GlowRect GenTexture rect2,rect2x; rect2.Init(256,256); rect2.LinearCombine(white,1.0f,0,0); // white background rect2.GlowRect(rect2,gradBW,0.5f,0.5f,0.36f,0.0f,0.0f,0.20f,0.8805f,0.74f); rect2x.Init(256,256); rect2x.CoordMatrixTransform(rect2,m3,GenTexture::WrapU|GenTexture::WrapV|GenTexture::FilterBilinear); // Multiply it over finalTex.Paste(finalTex,rect2x,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,GenTexture::CombineMultiply,0); } sInt totalTime = timeGetTime() - startTime; timeEndPeriod(1); printf("%d ms/tex\n",totalTime / 100); /*SaveImage(baseTex,"baseTex.tga"); SaveImage(finalTex,"final.tga");*/ return 0; }