Beispiel #1
0
void PLYObject::draw()
{

  // setup default material
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
  glColor3fv(diffuse);

  // set lighting if enabled
	// Otherwise, compute colors
  if (light)
		{
			glEnable(GL_LIGHTING);
		}
  else
		{

			glDisable(GL_LIGHTING);
			for (int v=0; v<nv; v++)
				{
					// Instead of this, use the Phong illumination equation to find the color

                    // Phong equation with attenuation factor att
                    // If = (As*Am) + ((Al*Am) + Id + Is) * att

                    // Get ModelView

                    float M[16];
                    Matrix4f modelViewMatrix;

                    glGetFloatv(GL_MODELVIEW_MATRIX, M);
                    for (int i = 0; i < 3; i++) {
                        modelViewMatrix[i][3] = 0.0;
                        modelViewMatrix[3][i] = 0.0;
                        for (int j = 0; j < 3; j++) {
                            modelViewMatrix[i][j] = M[i*4+j];
                        }
                    }
                    modelViewMatrix[3][3] = 1.0;

                    // ModelView is already here in a Matrix4f for operations

                    Vector3f vVertex;
                    multVector(vVertex, modelViewMatrix, vertices[v]);

                    Vector4f lightSource;
                    copy(lightSource, light_pos);
                    //glGetLightfv(GL_LIGHT0, GL_POSITION, lightSource);

                    Vector3f lightDir;
                    sub(lightDir, lightSource, vVertex);

                    float d = length(lightDir);

                    // Get parameters for the ambient part
                    float Al[4] = {0.0f, 0.0f, 0.0f, 0.0f };
                    glGetLightfv( GL_LIGHT0, GL_AMBIENT, Al );

                    Vector4f As = {0.0f, 0.0f, 0.0f, 0.0f };
                    glGetFloatv( GL_LIGHT_MODEL_AMBIENT, As );

                    float Dl[4] = {0.0f, 0.0f, 0.0f, 0.0f };
                    glGetLightfv( GL_LIGHT0, GL_DIFFUSE, Dl );

                    float Sl[4] = {0.0f, 0.0f, 0.0f, 0.0f };
                    glGetLightfv( GL_LIGHT0, GL_SPECULAR, Sl );

                    Vector4f Am = {0.0f, 0.0f, 0.0f, 0.0f };
                    copy(Am, ambient);

                    float Dm[4] = {0.0f, 0.0f, 0.0f, 0.0f };
                    copy(Dm, diffuse);

                    float Sm[4] = {0.0f, 0.0f, 0.0f, 0.0f };
                    copy(Sm, specular);

                    float f = shininess[0];  // copy shininess

                    float constantAttenuation = 0.0f;
                    glGetLightfv( GL_LIGHT0, GL_CONSTANT_ATTENUATION, &constantAttenuation);

                    float linearAttenuation = 0.0f;
                    glGetLightfv( GL_LIGHT0, GL_LINEAR_ATTENUATION , &linearAttenuation );

                    float quadraticAttenuation = 0.0f;
                    glGetLightfv( GL_LIGHT0, GL_QUADRATIC_ATTENUATION , &quadraticAttenuation);

                    float att = (constantAttenuation +
                                (linearAttenuation*d) +
                                (quadraticAttenuation*d*d) );

					// Start the phong equation with the ambient component
					Vector4f temp1;
					multVectors4(temp1, As, Am);
					Vector4f temp2;
                    multVectors4(temp2, Al, Am);
                    scale4(temp2, att);
					Vector4f final_color;
					//final_color = (As * Am) + (Al * Am)*att;
					add(final_color, temp1, temp2);

                    // Calculate lambertTerm
                    Vector3f N;
                    normalizeVector(N, normals[v]);
                    Vector3f L;
                    normalizeVector(L, lightDir);

                    float lambertTerm = dotProd(N,L);

                    if (lambertTerm > 0.0){
                        // diffuse component
                        multVectors4(temp1,Dl,Dm);
                        scale4(temp1,lambertTerm);
                        add(final_color, final_color, temp1);

                        // specular component
                        Vector3f E;
                        normalizeVector(E,viewer_pos);
                        Vector3f R;
                        scale4(temp1,lambertTerm*2,N);
                        sub(R, temp1, L); // reflect(-L,N)

                        float dotProduct = dotProd(R,E);
                        float specular_factor;
                        if(dotProduct > 0.0){
                            specular_factor = pow(dotProduct, f);
                        } else {
                            specular_factor = 0; // pow(0.0, f);
                        }

                        multVectors4(temp1, Sl, Sm);
                        scale4(temp1, specular_factor*att, temp1);
                        add(final_color, final_color, temp1);
                        // printf("DM are %f , %f and %f", final_color[0], final_color[1], final_color[2]);
                    }


                    //Colors [v][i] should take the colors of final_color, how?
                    colors[v][0] = final_color[0]*255;
                    colors[v][1] = final_color[1]*255;
                    colors[v][2] = final_color[2]*255;
				}
		}

	// Now do the actual drawing of the model
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glBegin(GL_TRIANGLES);

  for (int i = 0; i < nf; i++)
    {
      for (int j = 0; j < 3; j++)
        {
            glColor3ubv((GLubyte*)colors[faces[i][j]]);
            glNormal3fv(normals[faces[i][j]]);	// vertex normal
            glVertex3fv(vertices[faces[i][j]]);	// vertex coordinates
        }
    }
  glEnd();

  glDisable(GL_POLYGON_OFFSET_FILL);
  if (hascolor)
    glDisable(GL_COLOR_MATERIAL);
}
void ExportRegions()
{
	int counter = 0;
	
	int dim_x = g_mapInfo.width / g_mapInfo.visTableWidth;
	int dim_y = g_mapInfo.height / g_mapInfo.visTableWidth;

	Msg("World size:\n [%dx%d] vis cells\n [%dx%d] regions\n", g_mapInfo.width, g_mapInfo.height, dim_x, dim_y);

	// print region map to console
	for(int i = 0; i < g_numRegionOffsets; i++, counter++)
	{
		// Debug information: Print the map to the console.
		Msg(g_regionOffsets[i] == REGION_EMPTY ? "." : "O");
		if(counter == dim_x)
		{
			Msg("\n");
			counter = 0;
		}
	}

	Msg("\n");
	 
	int numCellObjectsRead = 0;

	IFile* objFile = NULL;
	IFile* levModelFile = NULL;

	objFile = GetFileSystem()->Open(varargs("%s_CELLPOS_MAP.obj", g_levname.c_str()), "wb", SP_ROOT);
	levModelFile = GetFileSystem()->Open(varargs("%s_LEVELMODEL.obj", g_levname.c_str()), "wb", SP_ROOT);

	levModelFile->Print("mtllib %s_LEVELMODEL.mtl\r\n", g_levname.c_str());

	int lobj_first_v = 0;
	int lobj_first_t = 0;

	// 2d region map
	// easy seeking
	for(int y = 0; y < dim_y; y++)
	{
		for(int x = 0; x < dim_x; x++)
		{
			int sPosIdx = y*dim_x + x;

			if(g_regionOffsets[sPosIdx] == REGION_EMPTY)
				continue;

			// determine region position
			int region_pos_x = x * 65536;
			int region_pos_z = y * 65536;

			// region at offset
			Spool* spool = (Spool*)((ubyte*)g_regionSpool + g_regionOffsets[sPosIdx]);

			Msg("---------\nSpool %d %d (offset: %d)\n", x, y, g_regionOffsets[sPosIdx]);
			Msg("offset: %d\n",spool->offset);

			Msg("connected areas offset: %d\n",spool->connected_areas);
			Msg("connected areas count: %d\n",spool->num_connected_areas);
			Msg("pvs block size: %d\n",spool->pvs_size);
			//Msg("padding: %d %d\n",spool->_padding,spool->_padding2);
			Msg("cell data size: %d\n",spool->cell_data_size);
			Msg("super regions: %d\n",spool->super_region);
			Msg("roadm size: %d\n",spool->roadm_size);
			Msg("roadh size: %d\n",spool->roadh_size);

			int cellsOffset = g_levInfo.spooldata_offset + 2048 * (spool->offset + spool->pvs_size + spool->cell_data_size);
			
			if(g_region_format.GetInt() == 2) // driver 2 demo
			{
				cellsOffset = g_levInfo.spooldata_offset + 2048 * (spool->offset + spool->pvs_size + spool->cell_data_size + spool->roadm_size );
			}
			else if(g_region_format.GetInt() == 1) // driver 1
			{
				ASSERT(!"diferrent packed cells used?\n");
			}

			Msg("cell objects ofs: %d\n", cellsOffset);

			RegionModels_t* regModels = NULL;

			// if region data is available, load models and textures
			if(spool->super_region != SUPERREGION_NONE)
			{
				regModels = &g_regionModels[spool->super_region];

				bool isNew = (regModels->modelRefs.numElem() == 0);

				LoadRegionData(g_levStream, regModels, &g_regionDataDescs[spool->super_region], &g_regionPages[spool->super_region]);

				if( g_export_models.GetBool() && isNew )
				{
					// export region models
					for(int i = 0; i < regModels->modelRefs.numElem(); i++)
					{
						int mod_indxex = regModels->modelRefs[i].index;

						EqString modelFileName = varargs("%s/ZREG%d_MOD_%d", g_levname_moddir.c_str(), spool->super_region, mod_indxex);

						if(g_model_names[mod_indxex].GetLength())
							modelFileName = varargs("%s/ZREG%d_%d_%s", g_levname_moddir.c_str(), spool->super_region, i, g_model_names[mod_indxex]);

						// export model
						ExportDMODELToOBJ(regModels->modelRefs[i].model, modelFileName.c_str(), regModels->modelRefs[i].index);
					}
				}
			}

			// seek to cells
			g_levStream->Seek(cellsOffset, VS_SEEK_SET);

			int cell_count = 0;

			objFile->Print("#--------\r\n# region %d %d (ofs=%d)\r\n", x, y, cellsOffset);
			objFile->Print("g cell_%d\r\n", sPosIdx);

			PACKED_CELL_OBJECT object;
			do
			{
				g_levStream->Read(&object, 1, sizeof(PACKED_CELL_OBJECT));
				
				// bad hack, need to parse visibility data for it
				if(	(0x4544 == object.pos_x && 0x2153 == object.addidx_pos_y) ||
					(0x4809 == object.pos_x && 0x4809 == object.addidx_pos_y) ||
					(0xA608 == object.pos_x && 0xA608 == object.addidx_pos_y) ||cell_count >= 8192)
					break;
				
				// unpack cell
				CELL_OBJECT cell;
				UnpackCellObject(object, cell);

				if(objFile)
				{
					objFile->Print("# m %d r %d\r\n", cell.modelindex, cell.rotation);
					objFile->Print("v %g %g %g\r\n", (region_pos_x+cell.x)*-0.00015f, cell.y*-0.00015f, (region_pos_z+cell.z)*0.00015f);
				}

				if(cell.modelindex >= g_levelModels.numElem())
				{
					Msg("cell model index invalid: %d\n", cell.modelindex);

					cell_count++;
					continue;
				}

				MODEL* model = FindModelByIndex(cell.modelindex, regModels);

				if(!model)
					break;

				// transform objects and save
				Matrix4x4 transform = translate(Vector3D((region_pos_x+cell.x)*-0.00015f, cell.y*-0.00015f, (region_pos_z+cell.z)*0.00015f));
				transform = transform * rotateY4(cell.rotation / 64.0f*PI_F*2.0f) * scale4(1.0f,1.0f,1.0f);

				WriteMODELToObjStream(levModelFile, model, cell.modelindex, false, transform, &lobj_first_v, &lobj_first_t, regModels);
				
				cell_count++;
			}while(true);

			MsgInfo("cell_count = %d\n", cell_count);

			if(objFile)
			{
				objFile->Print("# total region cells %d\r\n", cell_count);
			}

			numCellObjectsRead += cell_count;
		}
	}

	GetFileSystem()->Close(objFile);
	GetFileSystem()->Close(levModelFile);

	int numCellsObjectsFile = g_mapInfo.numAllObjects - g_mapInfo.numStraddlers;

	if(numCellObjectsRead != numCellsObjectsFile)
		MsgError("numAllObjects mismatch: in file: %d, read %d\n", numCellsObjectsFile, numCellObjectsRead);
}