Ejemplo n.º 1
0
void NzPatch::InitializeFromParent(NzTerrainNodeID nodeID, nzTerrainNodeData* data, const NzPatch& parentPatch)
{
    Reset();

    m_id = nodeID;
    m_data = data;

    int offx = 2 * (m_id.locx - std::floor(m_id.locx / 2.f) * 2);
    int offy = 2 * (m_id.locy - std::floor(m_id.locy / 2.f) * 2);

    m_vertices[1][1].SetPosition(parentPatch.m_vertices[1 + offx][1 + offy]);
    m_vertices[3][1].SetPosition(parentPatch.m_vertices[2 + offx][1 + offy]);
    m_vertices[5][1].SetPosition(parentPatch.m_vertices[3 + offx][1 + offy]);

    m_vertices[1][3].SetPosition(parentPatch.m_vertices[1 + offx][2 + offy]);
    m_vertices[3][3].SetPosition(parentPatch.m_vertices[2 + offx][2 + offy]);
    m_vertices[5][3].SetPosition(parentPatch.m_vertices[3 + offx][2 + offy]);

    m_vertices[1][5].SetPosition(parentPatch.m_vertices[1 + offx][3 + offy]);
    m_vertices[3][5].SetPosition(parentPatch.m_vertices[2 + offx][3 + offy]);
    m_vertices[5][5].SetPosition(parentPatch.m_vertices[3 + offx][3 + offy]);

    ComputeHeights();
    ComputeNormals();
    ComputeSlope();
}
Ejemplo n.º 2
0
//////////////////////////////////////////////////////////////////
//加载模型
bool CLoad3DS::Import3DS(t3DModel *pModel, char *strFileName)
{
	char strMessage[255] = {0};

	m_FilePointer = fopen(strFileName, "rb");

	if(!m_FilePointer) 
	{
		sprintf(strMessage, "Unable to find the file: %s!", strFileName);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}

	ReadChunk(m_CurrentChunk);

	if (m_CurrentChunk->ID != PRIMARY)
	{ 
		sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}

	ReadNextChunk(pModel, m_CurrentChunk);

	ComputeNormals(pModel);

	return true;
}
/// @brief Load a mesh from an OBJ file
BasicMesh::BasicMesh(const string &filename)
{
  if(!LoadOBJMesh(filename)) {
    exit(-1);
  }
  ComputeNormals();
}
bool C3DSLoader::Import3DS(t3DModel *pModel, char *strFileName)   
{      
	char strMessage[255] = {0};   

	m_FilePointer = fopen(strFileName, "rb");   

	if(!m_FilePointer)    
	{      
		sprintf(strMessage, "%s!", strFileName);   
		return false;   
	}   

	ReadChunk(m_CurrentChunk);   

	if (m_CurrentChunk->ID != PRIMARY)   
	{      
		return false;   
	}   

	ReadNextChunk(pModel, m_CurrentChunk);   
 
	ComputeNormals(pModel);   

	CleanUp();   

	return true;   
}   
Ejemplo n.º 5
0
void Terrain::Load()
{
	std::cout << "Loading Terrain" << std::endl;
	Texture* heightmap = new Texture();
	heightmap->SetFile(sFilepath);
	heightmap->Load();

	iWidth = heightmap->GetWidth();
	iLength = heightmap->GetHeight();

	pHeights = new float*[iLength];
	for(int i = 0; i < iLength; i++)
	{
		pHeights[i] = new float[iWidth];
	}

	vNormals = new glm::vec3*[iLength];
	for(int i = 0; i < iLength; i++)
	{
		vNormals[i] = new glm::vec3[iWidth];
	}

	for(int y = 0; y < iLength; y++)
	{
		for(int x = 0; x < iWidth; x++)
		{
			unsigned char color = heightmap->GetData()[3 * (y * iWidth + x)];
			float h = fScale * ((color / 255.0f) - 0.5f);
			SetHeight(x, y, h);
		}
	}

	delete heightmap;
	ComputeNormals();
}
Ejemplo n.º 6
0
glm::vec3 Terrain::GetNormal(int x, int z)
{
	if(!bNormalsComputed)
	{
		ComputeNormals();
	}

	return vNormals[z][x];
}
// 载入3ds文件
BOOL C3DSModel::Load(char *strFileName)
{
	char strMessage[128] = {0};
	tChunk chunk = {0};

	// 打开文件
	m_FilePtr = fopen(strFileName,"rb");

	// 如果文件打开失败
	if (!m_FilePtr)
	{
		sprintf(strMessage, "3DS文件 %s 不存在!", strFileName);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}

	// 读取3ds文件的第一个Chunk
	ReadChunk(&chunk);

	// 检查是否是3ds文件
	if (chunk.ID != PRIMARY)
	{
		sprintf(strMessage, "读取文件 %s 失败!", strFileName);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		fclose(m_FilePtr);
		return false;
	}

	// 开始读取3ds文件
	ReadPrimary(chunk.length-6);

	// 计算每个顶点的法线量
	ComputeNormals();

	// 关闭打开的文件
	fclose(m_FilePtr);
	m_FilePtr = NULL;

	// 对有纹理的材质载入该纹理
	for (int i=0; i<m_3DModel.numOfMaterials; i++)
	{
		if (m_3DModel.pMaterials[i].isTexMat)
		{
			if (!BuildTexture(m_3DModel.pMaterials[i].mapName.string, m_3DModel.pMaterials[i].texureId))
			{
				// 纹理载入失败
				sprintf(strMessage, "3DS纹理文件载入失败: %s !", m_3DModel.pMaterials[i].mapName.string);
				MessageBox(NULL, strMessage, "Error", MB_OK);
			}
		}
	}

	return true;
}
Ejemplo n.º 8
0
void NzPatch::Initialize(NzTerrainNodeID nodeID, nzTerrainNodeData* data)
{
    Reset();

    m_id = nodeID;
    m_data = data;

    ComputeHeights();
    ComputeNormals();
    ComputeSlope();
}
Ejemplo n.º 9
0
int Load3ds::ProcessNextObjectChunk(Chunk * aPreviousChunk)
{
	mCurrentChunk = new Chunk;
	size_t numberOfBytesRead;

	while (aPreviousChunk->mBytesRead < aPreviousChunk->mLength)
	{
		ReadChunk(mCurrentChunk);

		switch (mCurrentChunk->mID)
		{
		case OBJTRIMESH:
			// at this point, mBuffer will contain the name of the object being described
			ProcessNextObjectChunk(mCurrentChunk);
			ComputeNormals();

			break;

		case TRIVERT:
			FillVertexBuffer(mCurrentChunk);
			break;

		case TRIFACE:
			FillIndexBuffer(mCurrentChunk);
			break;

		case TRIFACEMAT:
			// your getting a list of triangles that belong to a certain material
			SortIndicesByMaterial(mCurrentChunk);
			break;

		case TRIUV:
			FillTexCoordBuffer(mCurrentChunk);
			break;

		default:  // unrecognized/unsupported chunk
			mCurrentChunk->mBytesRead += numberOfBytesRead = fread(mBuffer, 1, mCurrentChunk->mLength - mCurrentChunk->mBytesRead, mFile);
#ifdef __BIG_ENDIAN__
			for (int i = 0; i < numberOfBytesRead; i++)
				{
				static_cast<short *>(mBuffer)[i] = OSReadSwapInt16(&static_cast<short*>(mBuffer)[i],0);
				}
#endif
			break;
		}

	aPreviousChunk->mBytesRead += mCurrentChunk->mBytesRead;
	}

	delete mCurrentChunk;
	mCurrentChunk = aPreviousChunk;

	return 1;
}
Ejemplo n.º 10
0
void TriMesh<real>::InvalidateGeometry()
{
	ComputeNormals();

	// Update buffer
	if ( !mGeometryBuffer )
		mGeometryBuffer = new GeometryBuffer<real>( &mVertices[0], &mFaces[0].vertices[0], mVertices.size(), 3 * mFaces.size(), GeometryBuffer<real>::TypeTriangles, GeometryBuffer<real>::UsageStatic );
	else
	{
		mGeometryBuffer->UpdateVertices( &mVertices[0], mVertices.size() );
		mGeometryBuffer->UpdateIndices( &mFaces[0].vertices[0], 3 * mFaces.size() );
	}

	mGeometryBuffer->HasColors( mHasColors );
	mGeometryBuffer->HasNormals( mHasNormals );
	mGeometryBuffer->HasTexCoords( mHasTexCoords );
}
Ejemplo n.º 11
0
int Terrain::LoadFromImage(char* filename, int normal)
{
	Bitmap* bm = new Bitmap(filename, 1);
	int mode;
	float pointHeight;

	if(heights != NULL)
		Destroy();

	if(!bm->LoadBmp(filename, 1))
		return (TERRAIN_ERROR_LOADING_IMAGE);

	mode = bm->bpp / 8;

	if(mode != 3)
		return TERRAIN_ERROR_LOADING_IMAGE;

	width = bm->width;
	length = bm->height;

	heights = (float*)malloc(width * length * sizeof(float));
	if(heights == NULL)
		return (TERRAIN_ERROR_MEMORY_PROBLEM);

	if(normal)
	{
		normals = (float*)malloc(width * length * sizeof(float) * 3);
		if(normals == NULL)
			return (TERRAIN_ERROR_MEMORY_PROBLEM);
	}
	else
		normals = NULL;

	for(int i = 0; i<width; i++)
		for(int j = 0; j<length; j++)
		{
			pointHeight = (float)bm->data[i*width + j] / 256.0;
			heights[i * width + j] = pointHeight;
		}

	if(normals)
		ComputeNormals();

	return TERRAIN_OK;
}
Ejemplo n.º 12
0
bool CLoad3DS::Import3DS(t3DModel *pModel, char *strFileName)
{
	char strMessage[255] = {0};

	//FILE**m_FilePointer;
	// Open the 3DS file
	//m_FilePointer = fopen_s(strFileName, "rb");
    m_FilePointer =  fopen(strFileName, "rb");

	// Make sure we have a valid file pointer (we found the file)
	if(!m_FilePointer) 
	{
		sprintf(strMessage, "Unable to find the file: %s!", strFileName);
	//	MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}

	// Once we have the file open, we need to read the very first data chunk
	// to see if it's a 3DS file.  That way we don't read an invalid file.
	// If it is a 3DS file, then the first chunk ID will be equal to PRIMARY (some hex num)

	// Read the first chuck of the file to see if it's a 3DS file
	ReadChunk(m_CurrentChunk);

	// Make sure this is a 3DS file
	if (m_CurrentChunk->ID != PRIMARY)
	{
		sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);
		//MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}

	// Now we actually start reading in the data.  ProcessNextChunk() is recursive

	// Begin loading objects, by calling this recursive function
	ProcessNextChunk(pModel, m_CurrentChunk);

	// After we have read the whole 3DS file, we want to calculate our own vertex normals.
	ComputeNormals(pModel);

	// Clean up after everything
	CleanUp();

	return true;
}
Ejemplo n.º 13
0
int AseFile::Init(char *file_name, int MipLevels, int rotateX90, float scale, int loadNormalMap, int loadHeightMap)
{
	char strMessage[255]={0};

	DeleteAll();
	file = fopen( file_name, "rb");
	if(!file)
	{
		sprintf(strMessage, "Unable to find the file: %s!", file_name);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		return 0;
	}
	char *pdest = strrchr( file_name, '/' );
	if( pdest==NULL)directory[0]=NULL;
	else
	{
		strncpy( directory, file_name, pdest-file_name+1);
		directory[pdest-file_name+1]=NULL;
	}
	int ret = ReadAseFile();
	fclose( file );
	if(!ret)return 0;

	if(!LoadTexturesDiffuse(MipLevels))return 0;
	
	if(loadNormalMap)
		if(!LoadTexturesNormal(MipLevels))return 0;
	
	if(loadHeightMap)
		if(!LoadTexturesHeight(MipLevels))return 0;

	if(rotateX90)RotateX90();
	if(scale!=1.0f)Rescale( scale);
	MakeBoundingBoxs();

	for(int i=0; i<objects.size(); i++)
	//	if(objects[i].pFaceNormals==NULL || objects[i].pNormals==NULL)
			ComputeNormals(objects[i]);

	if(loadNormalMap)
		ComputeTangentBinormal();
	
	return 1;
}
Ejemplo n.º 14
0
bool Terrain::CreateTerrain(TerrainGenerator *generator){
	if (!generator){
		return false;
	}
	gridWidth = generator->GetWidth();
	gridDepth = generator->GetDepth();

	int mVertexCount = (gridWidth*gridDepth);
	vertices = new VertexNT[mVertexCount];

	heightData = new float[mVertexCount];

	float dx = CELLSPACING;
	float halfWidth = (gridWidth-1)*dx*0.5f;
	float halfDepth = (gridDepth-1)*dx*0.5f;	

	int index = 0;

	for(int i = 0; i < gridWidth; ++i){
		float z = halfDepth - i*dx;		
		for(int j = 0; j < gridDepth; ++j){
			float x = -halfWidth + j*dx;
			float y = generator->GetHeight(i,j);
			index = i*gridWidth+j;
			vertices[index].pos = D3DXVECTOR3(x, y, z);
			heightData[index] = y;
		}
	}

	maxHeight = generator->GetMaxHeight();
	
	ComputeTextureCoords();
	ComputeNormals();

	ComputeMeshQuadTree();	

	delete [] vertices;
	vertices = nullptr;
	delete [] indices;
	indices = nullptr;

	return true;
}
Ejemplo n.º 15
0
bool CLoad3DS::Import3DS(t3DModel *pModel, const wchar_t *strFileName)
{
	char strMessage[255] = {0};
	tChunk currentChunk = {0};

	// Open the 3DS file
	m_FilePointer = _wfopen(strFileName, L"rb");

	// Make sure we have a valid file pointer (we found the file)
	if(!m_FilePointer) 
	{
		XEVOL_LOG(eXL_DEBUG_HIGH, L"Unable to find the file: %S!\n", strFileName);
		return false;
	}

	// Once we have the file open, we need to read the very first data chunk
	// to see if it's a 3DS file.  That way we don't read an invalid file.
	// If it is a 3DS file, then the first chunk ID will be equal to PRIMARY (some hex num)

	// Read the first chuck of the file to see if it's a 3DS file
	ReadChunk(&currentChunk);

	// Make sure this is a 3DS file
	if (currentChunk.ID != PRIMARY)
	{
		XEVOL_LOG(eXL_DEBUG_HIGH, "Unable to load PRIMARY chuck from file: %s!", strFileName);
		return false;
	}

	// Now we actually start reading in the data.  ProcessNextChunk() is recursive

	// Begin loading objects, by calling this recursive function
	ProcessNextChunk(pModel, &currentChunk);

	// After we have read the whole 3DS file, we want to calculate our own vertex normals.
	ComputeNormals(pModel);

	// Clean up after everything
	CleanUp();

	return true;
}
Ejemplo n.º 16
0
bool Loaders::t3DSLoader::Import3DS(t3DModel *pModel, char *strFileName)
{
    char strMessage[255] = {0};

    m_FilePointer = fopen(strFileName, "rb");

    if(!m_FilePointer)
    {
        sprintf(strMessage, "Unable to find the file: %s!", strFileName);
        MessageBox(NULL, strMessage, "Error", MB_OK);
        return false;
    }

    ReadChunk(m_CurrentChunk);

    if (m_CurrentChunk->ID != PRIMARY)
    {
        sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName);
        MessageBox(NULL, strMessage, "Error", MB_OK);
        return false;
    }

    ProcessNextChunk(pModel, m_CurrentChunk);

    ResizeObjects(pModel);

    pModel->customScale.clear();
    pModel->customScale.resize(pModel->numberOfFrames);
    for (int i = 0; i < pModel->numberOfFrames; i++)
        pModel->customScale[i] = 1.0f;

    ComputeNormals(pModel);

    StoreMaximumMinimum(pModel);

    CleanUp();

    return true;
}
Ejemplo n.º 17
0
int Import3DS(Loader3ds *pt3ds,char *strFileName) 
{
 
	char strMessage[255] = {0}; 
	tChunk currentChunk = {0}; 
 
	// Open the 3DS file 
	pt3ds->FilePointer = fopen(strFileName, "rb"); 
 
	// Make sure we have a valid file pointer
	if(!pt3ds->FilePointer)  
	{ 
		sprintf(strMessage, "Unable to find the file: %s!", strFileName); 
		printf("%s\n",strMessage);
		return 0; 
	} 
 
	// Read the first chuck of the file to see if it's a 3DS file 
	ReadChunk(pt3ds,&currentChunk); 
 
	// Make sure this is a 3DS file 
	if (currentChunk.ID != PRIMARY) 
	{ 
		sprintf(strMessage, "Unable to load PRIMARY chuck from file: %s!", strFileName); 
		printf("%s\n",strMessage); 
		return 0; 
	} 

	//ProcessNextChunk() is recursive 
	ProcessNextChunk(pt3ds,&currentChunk); 
 
	// calculate vertex normals. 
	ComputeNormals(pt3ds); 
 
	if (pt3ds->FilePointer != NULL) fclose(pt3ds->FilePointer); 
 
	return 1; 
} 
Ejemplo n.º 18
0
Archivo: Ase.cpp Proyecto: RinM/CGA
bool CLoadASE::ImportASE(t3DModel *pModel, char *strFileName)
{
	char strMessage[255] = {0};

	if(!pModel || !strFileName) return false;

	m_FilePointer = fopen(strFileName, "r");

	if(!m_FilePointer) {
		sprintf(strMessage, "Unable to find or open the file: %s", strFileName);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}

	ReadAseFile(pModel);

	ComputeNormals(pModel);
	ComputeTangents(pModel);

	fclose(m_FilePointer);

	return true;
}
Ejemplo n.º 19
0
int Terrain::Scale(float min,float max) 
{
	float amp,aux,min1,max1,height;
	int total,i;

	if (heights == NULL)
		return(TERRAIN_ERROR_NOT_INITIALISED);

	if (min > max) 
	{
		aux = min;
		min = max;
		max = aux;
	}

	amp = max - min;
	total = width * length;

	min1 = heights[0];
	max1 = heights[0];
	for(i=1;i < total ; i++) 
	{
		if (heights[i] > max1)
			max1 = heights[i];
		if (heights[i] < min1)
			min1 = heights[i];
	}
	for(i=0;i < total; i++) 
	{
		height = (heights[i] - min1) / (max1-min1);
		heights[i] = height * amp - min;
	}
	printf("%f %f %f %f %f %f\n",min,max,min1,max1,amp,height);
	if (normals != NULL)
		ComputeNormals();
	return(TERRAIN_OK);
}
bool CLoad3DS::Import3DS(t3DModel *pModel, const char *strFileName)
{
	char strMessage[255] = {0};

	m_FilePointer = ASSET_OPEN(strFileName, "rb");

	if(!m_FilePointer) 
	{
		LOGI("%s does not exist", strFileName);
		return false;
	}
	ReadChunk(m_CurrentChunk);

	if (m_CurrentChunk->ID != PRIMARY)
	{
		return false;
	}
	ProcessNextChunk(pModel, m_CurrentChunk);
	ComputeNormals(pModel);

	CleanUp();

	return true;
}
Ejemplo n.º 21
0
void BasicMesh::Subdivide() {
  // Loop subdivision
  // NOTE The indices of the original set of vertices do not change after
  // subdivision. The new vertices are simply added to the set of vertices.
  // However, the faces change their indices after subdivision. See how new
  // faces are added to the face set for details.
  // In short, the new mesh is created as follows:
  //   [old vertices]
  //   [new vertices]
  //   [faces]

  // For each edge, compute its center point
  struct edge_t {
    edge_t() {}
    edge_t(int s, int t) : s(s), t(t) {}
    edge_t(const edge_t& e) : s(e.s), t(e.t) {}
    bool operator<(const edge_t& other) const {
      if(s < other.s) return true;
      else if( s > other.s ) return false;
      else return t < other.t;
    }
    int s, t;
  };

  struct face_edge_t {
    face_edge_t() {}
    face_edge_t(int fidx, edge_t e) : fidx(fidx), e(e) {}
    bool operator<(const face_edge_t& other) const {
      if(fidx < other.fidx) return true;
      else if(fidx > other.fidx) return false;
      return e < other.e;
    }
    int fidx;
    edge_t e;
  };

  const int num_faces = NumFaces();

  map<edge_t, Vector3d> midpoints;

  // iterate over all edges
  for (HalfEdgeMesh::EdgeIter e=hemesh.edges_begin(); e!=hemesh.edges_end(); ++e) {
    auto heh = hemesh.halfedge_handle(e, 0);
    auto hefh = hemesh.halfedge_handle(e, 1);

    auto v0h = hemesh.to_vertex_handle(heh);
    auto v1h = hemesh.to_vertex_handle(hefh);

    int v0idx = vhandles_map[v0h];
    int v1idx = vhandles_map[v1h];

    auto v0 = verts.row(v0idx);
    auto v1 = verts.row(v1idx);

    if(hemesh.is_boundary(*e)) {
      // simply compute the mid point
      midpoints.insert(make_pair(edge_t(v0idx, v1idx),
                                 0.5 * (v0 + v1)));
    } else {
      // use [1/8, 3/8, 3/8, 1/8] weights
      auto v2h = hemesh.to_vertex_handle(hemesh.next_halfedge_handle(heh));
      auto v3h = hemesh.to_vertex_handle(hemesh.next_halfedge_handle(hefh));

      int v2idx = vhandles_map[v2h];
      int v3idx = vhandles_map[v3h];

      auto v2 = verts.row(v2idx);
      auto v3 = verts.row(v3idx);

      midpoints.insert(make_pair(edge_t(v0idx, v1idx), (v0 * 3 + v1 * 3 + v2 + v3) / 8.0));
    }
  }

  // Now create a new set of vertices and faces
  const int num_verts = NumVertices() + midpoints.size();
  MatrixX3d new_verts(num_verts, 3);

  // Smooth these points
  for(int i=0;i<NumVertices();++i) {
    auto vh = vhandles[i];
    if(hemesh.is_boundary(vh)) {
      // use [1/8, 6/8, 1/8] weights
      auto heh = hemesh.halfedge_handle(vh);
      if(heh.is_valid()) {
        assert(hemesh.is_boundary(hemesh.edge_handle(heh)));

        auto prev_heh = hemesh.prev_halfedge_handle(heh);

        auto to_vh = hemesh.to_vertex_handle(heh);
        auto from_vh = hemesh.from_vertex_handle(prev_heh);

        Vector3d p = 6 * verts.row(i);
        p += verts.row(vhandles_map[to_vh]);
        p += verts.row(vhandles_map[from_vh]);
        p /= 8.0;
        new_verts.row(i) = p;
      }
    } else {
      // loop through the neighbors and count them
      int valence = 0;
      Vector3d p(0, 0, 0);
      for(auto vvit = hemesh.vv_iter(vh); vvit.is_valid(); ++vvit) {
        ++valence;
        p += verts.row(vhandles_map[*vvit]);
      }
      const double PI = 3.1415926535897;
      const double wa = (0.375 + 0.25 * cos(2.0 * PI / valence));
      const double w = (0.625 - wa * wa);
      p *= (w / valence);
      p += verts.row(i) * (1 - w);
      new_verts.row(i) = p;
    }
  }

  // Add the midpoints
  map<edge_t, int> midpoints_indices;
  int new_idx = NumVertices();
  for(auto p : midpoints) {
    midpoints_indices.insert(make_pair(p.first, new_idx));
    midpoints_indices.insert(make_pair(edge_t(p.first.t, p.first.s), new_idx));

    new_verts.row(new_idx) = p.second;
    ++new_idx;
  }

  // Process the texture coordinates
  map<face_edge_t, Vector2d> midpoints_texcoords;

  for(int fidx=0;fidx<NumFaces();++fidx){
    int j[] = {1, 2, 0};
    for(int i=0;i<3;++i) {
      int v0idx = faces(fidx, i);
      int v1idx = faces(fidx, j[i]);

      // if v0 = f[index_of(v0)], the tv0 = tf[index_of(v0)]
      int tv0idx = face_tex_index(fidx, i);
      // if v1 = f[index_of(v1)], the tv1 = tf[index_of(v1)]
      int tv1idx = face_tex_index(fidx, j[i]);

      auto t0 = texcoords.row(tv0idx);
      auto t1 = texcoords.row(tv1idx);

      // the texture coordinates is always the mid point
      midpoints_texcoords.insert(make_pair(face_edge_t(fidx, edge_t(v0idx, v1idx)),
                                           0.5 * (t0 + t1)));
    }
  }

  const int num_texcoords = texcoords.rows() + midpoints_texcoords.size();
  MatrixX2d new_texcoords(num_texcoords, 2);

  // Just copy the existing texture coordinates
  new_texcoords.topRows(texcoords.rows()) = texcoords;

  // Tex-coords for the mid points
  map<face_edge_t, int> midpoints_texcoords_indices;
  int new_texcoords_idx = texcoords.rows();
  for(auto p : midpoints_texcoords) {
    //cout << p.first.fidx << ": " << p.first.e.s << "->" << p.first.e.t << endl;
    //getchar();
    midpoints_texcoords_indices.insert(make_pair(p.first,
                                                 new_texcoords_idx));
    midpoints_texcoords_indices.insert(make_pair(face_edge_t(p.first.fidx, edge_t(p.first.e.t, p.first.e.s)),
                                                 new_texcoords_idx));

    new_texcoords.row(new_texcoords_idx) = p.second;
    ++new_texcoords_idx;
  }

  MatrixX3i new_faces(num_faces*4, 3);
  MatrixX3i new_face_tex_index(num_faces*4, 3);
  for(int i=0;i<num_faces;++i) {
    // vertex indices of the original triangle
    auto vidx0 = faces(i, 0);
    auto vidx1 = faces(i, 1);
    auto vidx2 = faces(i, 2);

    // texture coordinates indices of the original triangle
    auto tvidx0 = face_tex_index(i, 0);
    auto tvidx1 = face_tex_index(i, 1);
    auto tvidx2 = face_tex_index(i, 2);

    // indices of the mid points
    int nvidx01 = midpoints_indices[edge_t(vidx0, vidx1)];
    int nvidx12 = midpoints_indices[edge_t(vidx1, vidx2)];
    int nvidx20 = midpoints_indices[edge_t(vidx2, vidx0)];

    // indices of the texture coordinates of the mid points
    int tnvidx01 = midpoints_texcoords_indices.at(face_edge_t(i, edge_t(vidx0, vidx1)));
    int tnvidx12 = midpoints_texcoords_indices.at(face_edge_t(i, edge_t(vidx1, vidx2)));
    int tnvidx20 = midpoints_texcoords_indices.at(face_edge_t(i, edge_t(vidx2, vidx0)));

    // add the 4 new faces
    new_faces.row(i*4+0) = Vector3i(vidx0, nvidx01, nvidx20);
    new_faces.row(i*4+1) = Vector3i(nvidx20, nvidx01, nvidx12);
    new_faces.row(i*4+2) = Vector3i(nvidx20, nvidx12, vidx2);
    new_faces.row(i*4+3) = Vector3i(nvidx01, vidx1, nvidx12);

    new_face_tex_index.row(i*4+0) = Vector3i(tvidx0, tnvidx01, tnvidx20);
    new_face_tex_index.row(i*4+1) = Vector3i(tnvidx20, tnvidx01, tnvidx12);
    new_face_tex_index.row(i*4+2) = Vector3i(tnvidx20, tnvidx12, tvidx2);
    new_face_tex_index.row(i*4+3) = Vector3i(tnvidx01, tvidx1, tnvidx12);
  }

  verts = new_verts;
  faces = new_faces;
  texcoords = new_texcoords;
  face_tex_index = new_face_tex_index;

  // Update the normals after subdivision
  ComputeNormals();
}
Ejemplo n.º 22
0
void Sweep(Mesh& mesh) {

//    SweepHelper(mesh);

//    ComputeNormals(mesh);

    printf("original vertices: %ld\n", mesh.vertices.size()  );
    printf("original faces: %ld\n", mesh.faces.size()  );

//    printf("original mesh\n"  );

//    mesh.Print();


    HalfEdgeMesh m(mesh);




    /*
    for(auto it = m.beginEdges(); it != m.endEdges(); ++it) {

	glm::vec3 a;
	glm::vec3 b;

	it->GetEdgePoints(a,b);


	printf("Edge: %s § %s \n", glm::to_string(a).c_str(), glm::to_string(b).c_str() );
    }
*/

    printf("\n");

    printf("Original vertex size\n");
    printf("Num Faces: %ld\n", m.NumFaces() );
    printf("Num Vertices: %ld\n", m.NumVertices() );
    printf("Num Half Edges: %ld\n", m.NumHalfEdges() );
    printf("Num Edges: %ld\n", m.NumEdges() );
    printf("\n");

    auto it = m.beginEdges();

    for(int i = 0; i < 50; ++i) { // if 20, it hangs. but 50 works
	++it;
    }
//    m.Flip(it);
//    VertexIter v = m.Split(it);
//    m.Split(v->halfEdge->edge);


    VertexIter v  = m.Collapse(it);
    v = m.Collapse(v->halfEdge->edge);
//        m.Split(v->halfEdge->edge);

//        v = m.Collapse(v->halfEdge->edge);



    printf("Modified vertex size\n");
    printf("Num Faces: %ld\n", m.NumFaces() );
    printf("Num Vertices: %ld\n", m.NumVertices() );
    printf("Num Half Edges: %ld\n", m.NumHalfEdges() );
    printf("Num Edges: %ld\n", m.NumEdges() );
    printf("\n");


    printf("COLLAPSED\n");
/*
    it = m.beginEdges();
    for(int i = 0; i < 3; ++i) {
	++it;
    }
    m.Split(it);
*/


    //m.Flip(it);


//    printf("modified vertices: %ld\n", m.vertices.size()  );
//    printf("modified faces: %ld\n", m.faces.size()  );



    for(auto it = m.beginFaces(); it != m.endFaces(); ++it) {
	printf("Face edge count:%d \n", it->NumEdges() );
    }

    for(auto it = m.beginVertices(); it != m.endVertices(); ++it) {
	printf("Vertex degree:%d \n", it->Degree() );
    }




    printf("CONVERT TO MESH:\n");
    Mesh m2 = m.ToMesh();
    printf("MADE TO MESH\n");


/*
    printf("new vertices: %ld\n", m2.vertices.size()  );
    printf("new faces: %ld\n\n", m2.faces.size()  );
*/

//    m2.Print();

    mesh = m2;
    ComputeNormals(mesh);


    /*


      compute normals.

      for all edges, find this info: we need to have the indices of (c,d) for every triangle. (a,b) is already stored in edge ID.
      we keep this in a hash named edgeJacadcenties.(we find this as follows: iterate over all faces, for every edge in that
      face, we already have one of the opposite vertices, so add to pair! we do this for all faces).


      iterate over all faces:
      iterate over all edges, and add SORTED edge to stack(use set to make sure we process all edges only once)

      we keep a set of all added triangles.


      iterate until stack is empty:
      pop edge e of stack.
      if e should be split according to criterion
      split it. so compute midpoint m from (a and b) and add to list.
      now use midpoint to create four new triangles. use all of a,b,c,d to compute normal of m.

      now add all four new edges. BUT WHEN WE SPLIT, ENSURE THAT edgeJacadcenties is properly updated.

      else
      add both triangles(opposite to e), if necessary.

    */

}
Ejemplo n.º 23
0
bool CLoadMD2::ImportMD2(t3DModel *pModel, char *strFileName, char *strTexture)
{
	char strMessage[255] = {0};

	// Open the MD2 file in binary
	m_FilePointer = fopen(strFileName, "rb");

	// Make sure we have a valid file pointer (we found the file)
	if(!m_FilePointer) 
	{
		// Display an error message and don't load anything if no file was found
		sprintf(strMessage, "Unable to find the file: %s!", strFileName);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}
	
	// Just like most file formats, there is a header that needs to be read
	// from the .MD2 format.  If you look at the tMd2Header structure you will
	// find all the data that will be read in.  It's nice to know up front about
	// the data that we will be reading.  This makes it easy to just to large
	// binary reads using fread, instead of counting and reading chunks.

	// Read the header data and store it in our m_Header member variable
	fread(&m_Header, 1, sizeof(tMd2Header), m_FilePointer);

	// For some reason, .Md2 files MUST have a version of 8.  I am not sure why,
	// but if it doesn't there is something wrong and the header was read in
	// incorrectly, or perhaps the file format is bad.
	if(m_Header.version != 8)
	{
		// Display an error message for bad file format, then stop loading
		sprintf(strMessage, "Invalid file format (Version not 8): %s!", strFileName);
		MessageBox(NULL, strMessage, "Error", MB_OK);
		return false;
	}

	// Now that we made sure the header had correct data, we want to read in the
	// rest of the data.  Once the data is read in, we need to convert it to our structures.
	// Since we are only reading in the first frame of animation, there will only
	// be ONE object in our t3DObject structure, held within our pModel variable.
	ReadMD2Data();
	
	// Here we pass in our model structure to it can store the read Quake data
	// in our own model and object structure data.
	ConvertDataStructures(pModel);

	// After we have read the whole MD2 file, we want to calculate our own vertex normals.
	ComputeNormals(pModel);

	// If there is a valid texture name passed in, we want to set the texture data.
	if(strTexture)
	{
		// Create a local material info structure
		tMaterialInfo texture;

		// Copy the name of the file into our texture file name variable
		strcpy(texture.strFile, strTexture);

		// Since there is only one texture for a .MD2 file, the ID is always 0
		texture.texureId = 0;

		// The tile or scale for the UV's is 1 to 1 (but Quake saves off a 0-256 ratio)
		texture.uTile = texture.uTile = 1;

		// We only have 1 material for a model
		pModel->numOfMaterials = 1;

		// Add the local material info to our model's material list
		pModel->pMaterials.push_back(texture);
	}

	// Clean up after everything
	CleanUp();

	// Return a success
	return true;
}
Ejemplo n.º 24
0
/*
** void _3DS_LoadPolysets
*/
void _3DS_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets, qboolean verbose ){
	_3DS_t _3ds;
	int numPolysets;
	polyset_t *pPSET;
	triangle_t *ptri, *triangles;
	int i;

	// load the 3DS
	memset( &_3ds, 0, sizeof( _3ds ) );
	Load3DS( filename, &_3ds, verbose );

	// compute information
	numPolysets = _3ds.editChunk.numNamedObjects;

	// allocate memory
	pPSET = calloc( 1, numPolysets * sizeof( polyset_t ) );
	triangles = ptri = calloc( 1, POLYSET_MAXTRIANGLES * sizeof( triangle_t ) );

	// copy the data over
	for ( i = 0; i < numPolysets; i++ )
	{
		char matnamebuf[1024];
		int j;
		triangle_t *tri;
		_3DSTriObject_t *pTO = &_3ds.editChunk.pNamedObjects[i].pTriObjects[0];

		pPSET[i].triangles = ptri;
		pPSET[i].numtriangles = pTO->numFaces;
		strcpy( pPSET[i].name, _3ds.editChunk.pNamedObjects[i].name );

		strcpy( matnamebuf, filename );
		if ( strrchr( matnamebuf, '/' ) ) {
			*( strrchr( matnamebuf, '/' ) + 1 ) = 0;
		}
		strcat( matnamebuf, pTO->pMeshMaterialGroups[0].name );

		if ( strstr( matnamebuf, gamedir ) ) {
			strcpy( pPSET[i].materialname, strstr( matnamebuf, gamedir ) + strlen( gamedir ) );
		}
		else{
			strcpy( pPSET[i].materialname, pTO->pMeshMaterialGroups[0].name );
		}

		assert( pPSET[i].numtriangles < POLYSET_MAXTRIANGLES );

		for ( tri = ptri, j = 0; j < pPSET[i].numtriangles; j++ )
		{
			int i0 = pTO->pFaces[j].c;
			int i1 = pTO->pFaces[j].b;
			int i2 = pTO->pFaces[j].a;

			tri->verts[0][0] = pTO->pPoints[i0].x;
			tri->verts[0][1] = pTO->pPoints[i0].y;
			tri->verts[0][2] = pTO->pPoints[i0].z;

			tri->verts[1][0] = pTO->pPoints[i1].x;
			tri->verts[1][1] = pTO->pPoints[i1].y;
			tri->verts[1][2] = pTO->pPoints[i1].z;

			tri->verts[2][0] = pTO->pPoints[i2].x;
			tri->verts[2][1] = pTO->pPoints[i2].y;
			tri->verts[2][2] = pTO->pPoints[i2].z;
/*
            for ( k = 0; k < 3; k++ )
            {
                tri->colors[0][k] = 1;
                tri->colors[1][k] = 1;
                tri->colors[2][k] = 1;
            }
 */

			if ( pTO->pTexVerts ) {
				tri->texcoords[0][0] = pTO->pTexVerts[i0].s;
				tri->texcoords[0][1] = 1.0f - pTO->pTexVerts[i0].t;
				tri->texcoords[1][0] = pTO->pTexVerts[i1].s;
				tri->texcoords[1][1] = 1.0f - pTO->pTexVerts[i1].t;
				tri->texcoords[2][0] = pTO->pTexVerts[i2].s;
				tri->texcoords[2][1] = 1.0f - pTO->pTexVerts[i2].t;
			}

			tri++;
		}

		ptri += pPSET[i].numtriangles;
		assert( ptri - triangles < POLYSET_MAXTRIANGLES );
	}

	// compute normal data
#if 0
	for ( i = 0; i < numPolysets; i++ )
	{
		// unique vertices based solely on vertex position
		ComputeNormals( &_3ds.editChunk.pNamedObjects[i].pTriObjects[0],
						pPSET[i].triangles );
	}
#endif

	free( _3ds.editChunk.pMaterials );
	free( _3ds.editChunk.pNamedObjects );

	*ppPSET = pPSET;
	*numpsets = numPolysets;
}