예제 #1
0
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);
}
예제 #2
0
파일: grcar.cpp 프로젝트: andypassion/torcs
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;
}