void save_database(void) { int i; tFace *curFace; sgMat4 m; ssgBranch *b = new ssgBranch(); sgMakeIdentMat4(m); for (i = 0; i < NbRows; i++) { curFace = GF_TAILQ_FIRST(&(Row[i].faces)); while (curFace) { if (curFace->isPresent) { curFace->branch->setTransform(m); ssgFlatten(curFace->branch); ssgStripify(curFace->branch); } curFace = GF_TAILQ_NEXT(curFace, link); } } b->addKid(Root); ssgFlatten(Root); ssgStripify(Root); myssgSaveAC(OutputFileName, b, SkinFileName); }
static ssgTransform *initWheel(tCarElt *car, int wheel_index) { int i, j, k; float alpha; sgVec3 vtx; sgVec4 clr; sgVec3 nrm; sgVec2 tex; tdble b_offset = 0.0f; tdble curAngle = 0.0f; #define BRK_BRANCH 16 #define BRK_ANGLE (2.0 * M_PI / (tdble)BRK_BRANCH) #define BRK_OFFSET 0.2 switch(wheel_index) { case FRNT_RGT: curAngle = -(M_PI / 2.0 + BRK_ANGLE); b_offset = BRK_OFFSET - car->_tireWidth(wheel_index) / 2.0; break; case FRNT_LFT: curAngle = -(M_PI / 2.0 + BRK_ANGLE); b_offset = car->_tireWidth(wheel_index) / 2.0 - BRK_OFFSET; break; case REAR_RGT: curAngle = (M_PI / 2.0 - BRK_ANGLE); b_offset = BRK_OFFSET - car->_tireWidth(wheel_index) / 2.0; break; case REAR_LFT: curAngle = (M_PI / 2.0 - BRK_ANGLE); b_offset = car->_tireWidth(wheel_index) / 2.0 - BRK_OFFSET; break; } /* hub */ ssgVertexArray *brk_vtx = new ssgVertexArray(BRK_BRANCH + 1); ssgColourArray *brk_clr = new ssgColourArray(1); ssgNormalArray *brk_nrm = new ssgNormalArray(1); tdble hubRadius; /* center */ vtx[0] = vtx[2] = 0.0; vtx[1] = b_offset; brk_vtx->add(vtx); hubRadius = car->_brakeDiskRadius(wheel_index) * 0.6; for (i = 0; i < BRK_BRANCH; i++) { alpha = (float)i * 2.0 * M_PI / (float)(BRK_BRANCH - 1); vtx[0] = hubRadius * cos(alpha); vtx[1] = b_offset; vtx[2] = hubRadius * sin(alpha); brk_vtx->add(vtx); } clr[0] = clr[1] = clr[2] = 0.0; clr[3] = 1.0; brk_clr->add(clr); nrm[0] = nrm[2] = 0.0; // Make normal point outside to have proper lighting. switch(wheel_index) { case FRNT_RGT: case REAR_RGT: nrm[1] = -1.0; break; case FRNT_LFT: case REAR_LFT: nrm[1] = 1.0; break; } brk_nrm->add(nrm); ssgVtxTable *brk = new ssgVtxTable(GL_TRIANGLE_FAN, brk_vtx, brk_nrm, NULL, brk_clr); brk->setCullFace(0); brk->setState(commonState); ssgTransform *wheel = new ssgTransform; wheel->addKid(brk); /* Brake disk */ brk_vtx = new ssgVertexArray(BRK_BRANCH + 4); brk_clr = new ssgColourArray(1); brk_nrm = new ssgNormalArray(1); for (i = 0; i < (BRK_BRANCH / 2 + 2); i++) { alpha = curAngle + (float)i * 2.0 * M_PI / (float)(BRK_BRANCH - 1); vtx[0] = car->_brakeDiskRadius(wheel_index) * cos(alpha); vtx[1] = b_offset; vtx[2] = car->_brakeDiskRadius(wheel_index) * sin(alpha); brk_vtx->add(vtx); vtx[0] = car->_brakeDiskRadius(wheel_index) * cos(alpha) * 0.6; vtx[1] = b_offset; vtx[2] = car->_brakeDiskRadius(wheel_index) * sin(alpha) * 0.6; brk_vtx->add(vtx); } clr[0] = clr[1] = clr[2] = 0.1; clr[3] = 1.0; brk_clr->add(clr); //nrm[0] = nrm[2] = 0.0; //nrm[1] = 1.0; brk_nrm->add(nrm); brk = new ssgVtxTable(GL_TRIANGLE_STRIP, brk_vtx, brk_nrm, NULL, brk_clr); brk->setCullFace(0); brk->setState(brakeState); grCarInfo[grCarIndex].brkColor[wheel_index] = brk_clr; wheel->addKid(brk); /* Brake caliper */ brk_vtx = new ssgVertexArray(BRK_BRANCH - 4); brk_clr = new ssgColourArray(1); brk_nrm = new ssgNormalArray(1); for (i = 0; i < (BRK_BRANCH / 2 - 2); i++) { alpha = - curAngle + (float)i * 2.0 * M_PI / (float)(BRK_BRANCH - 1); vtx[0] = (car->_brakeDiskRadius(wheel_index) + 0.02) * cos(alpha); vtx[1] = b_offset; vtx[2] = (car->_brakeDiskRadius(wheel_index) + 0.02) * sin(alpha); brk_vtx->add(vtx); vtx[0] = car->_brakeDiskRadius(wheel_index) * cos(alpha) * 0.6; vtx[1] = b_offset; vtx[2] = car->_brakeDiskRadius(wheel_index) * sin(alpha) * 0.6; brk_vtx->add(vtx); } clr[0] = 0.2; clr[1] = 0.2; clr[2] = 0.2; clr[3] = 1.0; brk_clr->add(clr); //nrm[0] = nrm[2] = 0.0; //nrm[1] = 1.0; brk_nrm->add(nrm); brk = new ssgVtxTable(GL_TRIANGLE_STRIP, brk_vtx, brk_nrm, NULL, brk_clr); brk->setCullFace(0); brk->setState(commonState); wheel->addKid(brk); DBG_SET_NAME(wheel, "Wheel", grCarIndex, wheel_index); grCarInfo[grCarIndex].wheelPos[wheel_index] = wheel; /* wheels */ ssgTransform *whrotation = new ssgTransform; grCarInfo[grCarIndex].wheelRot[wheel_index] = whrotation; wheel->addKid(whrotation); ssgSelector *whselector = new ssgSelector; whrotation->addKid(whselector); grCarInfo[grCarIndex].wheelselector[wheel_index] = whselector; float wheelRadius = car->_rimRadius(wheel_index) + car->_tireHeight(wheel_index); // Create wheels for 4 speeds (stillstanding - fast --> motion blur, look at the texture). for (j = 0; j < 4; j++) { ssgBranch *whl_branch = new ssgBranch; ssgEntity *whl3d = 0; // load speed-dependant 3D wheels if available and if detailed wheels are desired. // wheel data files are located in the wheels directory. first set directory. if (grUseDetailedWheels == DETAILED) { const int bufsize = 1024; char buf[bufsize]; const char* wheel_dir = GfParmGetStr(car->_carHandle, SECT_GROBJECTS, PRM_WHEEL_3D_DIR, 0); if (wheel_dir != 0) { snprintf(buf, bufsize, "wheels/%s", wheel_dir); ssgModelPath(buf); ssgTexturePath(buf); } // set basename for wheel file 0..3 gets appended const char* wheel_obj = GfParmGetStr(car->_carHandle, SECT_GROBJECTS, PRM_WHEEL_3D, 0); if (wheel_obj != 0 && wheel_dir != 0) { snprintf(buf, bufsize, "%s%d.acc", wheel_obj, j); whl3d = grssgCarLoadAC3D(buf, NULL, car->index); } } // if we have a 3D wheel, use it. otherwise use normal generated wheel... if (whl3d) { // Adapt size of the wheel ssgTransform *whl_size = new ssgTransform; sgMat4 wheelsz; sgSetVec4(wheelsz[0], wheelRadius * 2, SG_ZERO, SG_ZERO, SG_ZERO) ; sgSetVec4(wheelsz[1], SG_ZERO, car->_tireWidth(wheel_index), SG_ZERO, SG_ZERO) ; sgSetVec4(wheelsz[2], SG_ZERO, SG_ZERO, wheelRadius * 2, SG_ZERO) ; sgSetVec4(wheelsz[3], SG_ZERO, SG_ZERO, SG_ZERO, SG_ONE) ; whl_size->setTransform(wheelsz); whl_size->addKid(whl3d); whl3d = whl_size; if (wheel_index == FRNT_RGT || wheel_index == REAR_RGT) { // flip wheel around so it faces the right way ssgTransform *whl_mesh_transform = new ssgTransform; sgCoord wheelpos; sgSetCoord(&wheelpos, 0, 0, 0, 180, 0, 0); whl_mesh_transform->setTransform( &wheelpos); whl_mesh_transform->addKid(whl3d); whl_branch->addKid(whl_mesh_transform); } else { whl_branch->addKid(whl3d); } } else { static sgVec2 toffset[4] = { {0.0, 0.5}, {0.5, 0.5}, {0.0, 0.0}, {0.5, 0.0} }; // TORCS's standard generated wheel const int WHL_BRANCH = 16; /* Tread */ { ssgVertexArray *whl_vtx = new ssgVertexArray(2 * WHL_BRANCH); ssgColourArray *whl_clr = new ssgColourArray(2 * WHL_BRANCH); ssgNormalArray *whl_nrm = new ssgNormalArray(1); whl_nrm->add(nrm); clr[3] = 1.0; for (i = 0; i < WHL_BRANCH; i++) { alpha = (float)i * 2.0 * M_PI / (float)(WHL_BRANCH - 1); vtx[0] = wheelRadius * cos(alpha); vtx[2] = wheelRadius * sin(alpha); vtx[1] = - car->_tireWidth(wheel_index) / 2.0; whl_vtx->add(vtx); vtx[1] = car->_tireWidth(wheel_index) / 2.0; whl_vtx->add(vtx); if (i % 2) { clr[0] = clr[1] = clr[2] = 0.15; } else { clr[0] = clr[1] = clr[2] = 0.0; } whl_clr->add(clr); whl_clr->add(clr); } ssgVtxTable *whl = new ssgVtxTable(GL_TRIANGLE_STRIP, whl_vtx, whl_nrm, NULL, whl_clr); whl->setState(commonState); whl->setCullFace(0); // stripify wheel, should improve performance ssgStripify(whl); whl_branch->addKid(whl); } /* Rim */ switch(wheel_index) { case FRNT_RGT: case REAR_RGT: b_offset = -0.05; break; case FRNT_LFT: case REAR_LFT: b_offset = 0.05; break; } // Make inside rim very dark and take care of normals. float colorfactor[2]; float norm_orig = nrm[1]; if (nrm[1] > 0.0f) { colorfactor[0] = 0.3f; colorfactor[1] = 1.0f; nrm[1] *= -1.0f; } else { colorfactor[0] = 1.0f; colorfactor[1] = 0.3f; } for (k = 0; k < 2; k++) { ssgVertexArray *whl_vtx = new ssgVertexArray(WHL_BRANCH + 1); ssgTexCoordArray *whl_tex = new ssgTexCoordArray(WHL_BRANCH + 1); ssgColourArray *whl_clr = new ssgColourArray(1); ssgNormalArray *whl_nrm = new ssgNormalArray(1); clr[0] = 0.8f*colorfactor[k]; clr[1] = 0.8f*colorfactor[k]; clr[2] = 0.8f*colorfactor[k]; clr[3] = 1.0f; whl_clr->add(clr); whl_nrm->add(nrm); vtx[0] = vtx[2] = 0.0; vtx[1] = (float)(2 * k - 1) * car->_tireWidth(wheel_index) / 2.0 - b_offset; whl_vtx->add(vtx); tex[0] = 0.25 + toffset[j][0]; tex[1] = 0.25 + toffset[j][1]; whl_tex->add(tex); vtx[1] = (float)(2 * k - 1) * car->_tireWidth(wheel_index) / 2.0; for (i = 0; i < WHL_BRANCH; i++) { alpha = (float)i * 2.0 * M_PI / (float)(WHL_BRANCH - 1); vtx[0] = wheelRadius * cos(alpha); vtx[2] = wheelRadius * sin(alpha); whl_vtx->add(vtx); tex[0] = 0.25 + 0.25 * cos(alpha) + toffset[j][0]; tex[1] = 0.25 + 0.25 * sin(alpha) + toffset[j][1]; whl_tex->add(tex); } ssgVtxTable *whl = new ssgVtxTable(GL_TRIANGLE_FAN, whl_vtx, whl_nrm, whl_tex, whl_clr); whl->setState(grCarInfo[grCarIndex].wheelTexture); whl->setCullFace(0); // stripify rim, should improve performance ssgStripify(whl); whl_branch->addKid(whl); // Swap normal for "inside" rim face. nrm[1] *= -1.0; } nrm[1] = norm_orig; } whselector->addKid(whl_branch); } return wheel; }