bool NifImporter::ImportMesh(NiTriShapeRef triShape)
{
   bool ok = true;

   ImpNode *node = i->CreateNode();
   if(!node)
	   return false;
   TriObject *triObject = CreateNewTriObject();
   node->Reference(triObject);
   wstring name = wide(triShape->GetName());
   node->SetName(name.c_str());
   INode *inode = node->GetINode();
   imports.push_back(inode);

   // Texture
   Mesh& mesh = triObject->GetMesh();
   NiTriShapeDataRef triShapeData = DynamicCast<NiTriShapeData>(triShape->GetData());
   if (triShapeData == NULL)
      return false;

   vector<Triangle> tris = triShapeData->GetTriangles();
   ok |= ImportMesh(node, triObject, triShape, triShapeData, tris);
   return ok;
}
/*---------------------------------------------------------------------------*/
NiTriShapeRef NifConvertUtility::convertNiTriStrips(NiTriStripsRef pSrcNode, NiTriShapeRef pTmplNode, NiAlphaPropertyRef pTmplAlphaProp)
{
	NiTriShapeRef			pDstNode   (new NiTriShape());
	NiTriShapeDataRef		pDstGeo    (new NiTriShapeData());
	NiTriStripsDataRef		pSrcGeo    (DynamicCast<NiTriStripsData>(pSrcNode->GetData()));
	vector<NiPropertyRef>	srcPropList(pSrcNode->GetProperties());

	//  copy NiTriStrips to NiTriShape
	pDstNode->SetCollisionObject(NULL);  //  no collision object here
	pDstNode->SetFlags          (14);    //  ???
	pDstNode->SetName           (pSrcNode->GetName());
	pDstNode->SetLocalTransform (pSrcNode->GetLocalTransform());
	pDstNode->SetData           (pDstGeo);

	//  move properties
	for (auto pIter=srcPropList.begin(), pEnd=srcPropList.end(); pIter != pEnd; ++pIter)
	{
		if (DynamicCast<NiVertexColorProperty>(*pIter) != NULL)
		{
			int	iii=0;
		}
		pDstNode->AddProperty(*pIter);
	}
	pSrcNode->ClearProperties();

	//  data node
	if (pSrcGeo != NULL)
	{
		pDstGeo->SetVertices    (pSrcGeo->GetVertices());
		pDstGeo->SetNormals     (pSrcGeo->GetNormals());
		pDstGeo->SetTriangles   (pSrcGeo->GetTriangles());
		pDstGeo->SetVertexColors(pSrcGeo->GetColors());
		pDstGeo->SetUVSetCount  (pSrcGeo->GetUVSetCount());
		for (short idx(0), max(pSrcGeo->GetUVSetCount()); idx < max; ++idx)
		{
			pDstGeo->SetUVSet(idx, pSrcGeo->GetUVSet(idx));
		}
	}  //  if (pSrcGeo != NULL)

	//  return converted NiTriShape
	return convertNiTri(pDstNode, pTmplNode, pTmplAlphaProp);
}
Exemple #3
0
void addToNif(Land l, long offx, long offy, CellMeshList& cml){
	using namespace Niflib;

	std::vector<Vector3> verts;
	std::vector<Vector3> normals;
	std::vector<TexCoord> txCoords;
	std::vector<Triangle> tris;


	for ( int x = 0; x < 65; x++){
		for ( int y = 0; y < 65; y++){
			verts.push_back(
				Vector3(x*128,y*128,l.land[x][y]*8)
			);

			//vector needs to be normalized
			float nx = l.normals[x][y].x;
			float ny = l.normals[x][y].y;
			float nz = l.normals[x][y].z;
			float mag = sqrt(nx*nx+ny*ny+nz*nz);
			nx/=mag;
			ny/=mag;
			nz/=mag;

			normals.push_back(
				Vector3(nx,ny,nz)
			);

			txCoords.push_back(
				TexCoord(x/(float)65, y/(float)65)
			);
		}
	}

	//ak. Hacky
	const unsigned vertNum = 65 * 65;
	const unsigned meshLength = sqrt((float) vertNum);

	const unsigned loopSize = (vertNum) - (meshLength * 2) + 65;
	for( unsigned i = 0; i < loopSize; i++){
		unsigned iTmp = i;
		while ( iTmp > (meshLength - 1) )
			iTmp -= meshLength;

		if ( iTmp == (meshLength - 1) )
			continue;

		Triangle tri;

		tri.v1 = i;
		tri.v2 = i + meshLength;
		tri.v3 = i + 1;
		tris.push_back(tri);


		tri.v1 = i + meshLength;
		tri.v2 = i + meshLength + 1;
		tri.v3 = i + 1;
		tris.push_back(tri);
	}

	NiTriShapeRef shape = new NiTriShape;
	shape->SetName("TxtMesh");
	shape->AddProperty(getMatProp());
	shape->AddProperty(getTexture());


	NiTriShapeDataRef triData = new NiTriShapeData;
	triData->SetVertices(verts);
	triData->SetNormals(normals);
	triData->SetTriangles(tris);

	//uv
	triData->SetUVSetCount(1);
	triData->SetUVSet(0, txCoords);

	//ad it to the TriShape
	NiGeometryDataRef gRef = DynamicCast<NiGeometryData>( triData );
	shape->SetData(gRef);


	NiAVObjectRef avObj = DynamicCast<NiAVObject>(  shape );

	//make it so the center of the cell is on 0, 0
	Vector3 vec3;
	vec3.x = offx;
	vec3.y = offy;
	avObj->SetLocalTranslation(vec3);

	cml.push_back(avObj);
}
Exemple #4
0
MeshData *CMesh::AddTriShape(NiTriShapeRef trishapenode)
{
	unsigned long index;
	MeshData *newmeshpart;
	MeshVertex *davert;
	unsigned short *daind;

	if(trishapenode==NULL) return NULL;

	NiGeometryDataRef ergeom = trishapenode->GetData();
	NiTriShapeDataRef geom = DynamicCast<NiTriShapeData>(ergeom);
	if(geom==NULL)
	{
		output_text(L"Couldn't cast to NiTriStripsData!\r\n");
		return NULL;
	}


	if(geom->GetUVSetCount()==0||geom->GetTriangles().size()==0)
	{
		if(geom->GetUVSetCount()==0) output_text_hex(L"No UV Set:",formID);
		if(geom->GetTriangles().size()==0) output_text_hex(L"No Triangles:",formID);
		return NULL;
	}
	
	//Get the vertices
	vector<Vector3> davertices=geom->GetVertices();
	//Get the uvs
	vector<TexCoord> dauvs=geom->GetUVSet(0);
	//Get the normals
	vector<Vector3> danormals=geom->GetNormals();
	//Get the colors
	vector<Color4> dacolors=geom->GetColors();
	//Get the indices
	vector<Triangle> daindices=geom->GetTriangles();

	newmeshpart=new MeshData;

	//Get the number of vertex
	newmeshpart->numvert=geom->GetVertexCount();
	//Get the number of indices
	newmeshpart->numind=daindices.size()*3;
	//newmeshpart->numind=geom->GetVertexIndexCount();

	//output_text_value(L"Number of vertex:",newmeshpart->numvert);
	//output_text_value(L"Number of indices:",newmeshpart->numind);

	if(newmeshpart->numvert==0||newmeshpart->numind==0)
	{
		if(newmeshpart->numvert==0) output_text_hex(L"No vertex?:",formID);
		if(newmeshpart->numind==0) output_text_hex(L"No indices?:",formID);
		delete newmeshpart;
		return NULL;
	}

	davert=new MeshVertex[newmeshpart->numvert];
	daind=new unsigned short[newmeshpart->numind];

	for(index=0;index<(newmeshpart->numind/3);index++)
	{
		//memcpy later
		//daind[index]=daindices[(newmeshpart->numind-1)-index];
		daind[index*3]=daindices[index].v1;
		daind[(index*3)+1]=daindices[index].v2;
		daind[(index*3)+2]=daindices[index].v3;
		
	}

	for(index=0;index<newmeshpart->numvert;index++)
	{
		//change to use memcpy later
		davert[index].Pos.x=davertices[index].x;
		davert[index].Pos.y=davertices[index].y;
		davert[index].Pos.z=davertices[index].z;
		davert[index].TextUV.x=dauvs[index].u;
		davert[index].TextUV.y=dauvs[index].v;
		davert[index].Norm.x=danormals[index].x;
		davert[index].Norm.y=danormals[index].y;
		davert[index].Norm.z=danormals[index].z;
	}

	if(dacolors.size()!=0)
	{
		for(index=0;index<newmeshpart->numvert;index++)
		{
			davert[index].Color.x=dacolors[index].r;
			davert[index].Color.y=dacolors[index].g;
			davert[index].Color.z=dacolors[index].b;
			davert[index].Color.w=dacolors[index].a;
		}
	}
	else
	{
		for(index=0;index<newmeshpart->numvert;index++)
		{
			davert[index].Color.x=1.0f;
			davert[index].Color.y=1.0f;
			davert[index].Color.z=1.0f;
			davert[index].Color.w=1.0f;
		}
	}

	//Load the texture
	vector<NiPropertyRef> daprops=trishapenode->GetProperties();
	bool foundtext=false;
	for(index=0;index<daprops.size();index++)
	{
		if(daprops[index]->IsSameType(NiTexturingProperty::TYPE))
		{
			NiTexturingPropertyRef datextprop=DynamicCast<NiTexturingProperty>(daprops[index]);
			if(datextprop==NULL)
			{
				output_text(L"Failed NiTexturingProperty Cast!\r\n");
				delete newmeshpart;
				delete [] davert;
				delete [] daind;
				return NULL;
			}
			foundtext=true;
			TexDesc datextdesc=datextprop->GetTexture(0);
			newmeshpart->datext=pTextureManager->Load_Direct((char *)datextdesc.source->GetTextureFileName().c_str());
			break;
		}
	}

	if(foundtext==false) output_text_hex(L"Couldn't find texture:",formID);

	newmeshpart->pIndiceBuf=pDXManager->CreateIndiceBuffer((unsigned char *)daind,newmeshpart->numind,sizeof(unsigned short));
	newmeshpart->pVertexBuf=pDXManager->CreateVertexBuffer((unsigned char *)davert,newmeshpart->numvert,sizeof(MeshVertex));

	delete [] daind;
	delete [] davert;
	
	//Ok now let's add it
	listdata.push_back(newmeshpart);

	return newmeshpart;
}
/*---------------------------------------------------------------------------*/
bool NifConvertUtility::updateTangentSpace(NiTriShapeDataRef pDataObj)
{
	vector<Vector3>		vecVertices (pDataObj->GetVertices());
	vector<Vector3>		vecNormals  (pDataObj->GetNormals());
	if(vecVertices.size() > 0 && ! pDataObj->GetUVSetCount() ) {
		logMessage(NCU_MSG_TYPE_INFO, "UpdateTangentSpace: has vertices but not UV");
		return false;
	}
	vector<TexCoord>	vecTexCoords(pDataObj->GetUVSet(0) );
	vector<Triangle>	vecTriangles(pDataObj->GetTriangles());


	//  check on valid input data
	if (vecVertices.empty() || vecTriangles.empty() || vecNormals.size() != vecVertices.size() || vecVertices.size() != vecTexCoords.size())
	{
		logMessage(NCU_MSG_TYPE_INFO, "UpdateTangentSpace: No vertices, normals, coords or faces defined.");
		return false;
	}

	//  prepare result vectors
	vector<Vector3>		vecTangents  = vector<Vector3>(vecVertices.size(), Vector3(0.0f, 0.0f, 0.0f));
	vector<Vector3>		vecBiNormals = vector<Vector3>(vecVertices.size(), Vector3(0.0f, 0.0f, 0.0f));

	for (unsigned int t(0); t < vecTriangles.size(); ++t)
	{
		Vector3		vec21(vecVertices[vecTriangles[t][1]] - vecVertices[vecTriangles[t][0]]);
		Vector3		vec31(vecVertices[vecTriangles[t][2]] - vecVertices[vecTriangles[t][0]]);
		TexCoord	txc21(vecTexCoords[vecTriangles[t][1]] - vecTexCoords[vecTriangles[t][0]]);
		TexCoord	txc31(vecTexCoords[vecTriangles[t][2]] - vecTexCoords[vecTriangles[t][0]]);
		float		radius(((txc21.u * txc31.v - txc31.u * txc21.v) >= 0.0f ? +1.0f : -1.0f));

		Vector3		sdir(( txc31.v * vec21[0] - txc21.v * vec31[0] ) * radius,
					     ( txc31.v * vec21[1] - txc21.v * vec31[1] ) * radius,
					     ( txc31.v * vec21[2] - txc21.v * vec31[2] ) * radius);
		Vector3		tdir(( txc21.u * vec31[0] - txc31.u * vec21[0] ) * radius,
					     ( txc21.u * vec31[1] - txc31.u * vec21[1] ) * radius,
					     ( txc21.u * vec31[2] - txc31.u * vec21[2] ) * radius);

		//  normalize
		sdir = sdir.Normalized();
		tdir = tdir.Normalized();

		for (int j(0); j < 3; ++j)
		{
			vecTangents [vecTriangles[t][j]] += tdir;
			vecBiNormals[vecTriangles[t][j]] += sdir;
		}
	}  //  for (unsigned int t(0); t < vecTriangles.size(); ++t)

	for (unsigned int i(0); i < vecVertices.size(); ++i)
	{
		Vector3&	n(vecNormals[i]);
		Vector3&	t(vecTangents [i]);
		Vector3&	b(vecBiNormals[i]);

		if ((t == Vector3()) || (b == Vector3()))
		{
			t[0] = n[1];
			t[1] = n[2];
			t[2] = n[0];

			b = n.CrossProduct(t);
		}
		else
		{
			t = t.Normalized();
			t = (t - n * n.DotProduct(t));
			t = t.Normalized();

			b = b.Normalized();
			b = (b - n * n.DotProduct(b));
			b = (b - t * t.DotProduct(b));
			b = b.Normalized();
		}
	}  //  for (unsigned int i(0); i < vecVertices.size(); ++i)

	//  set tangents and binormals to object
	pDataObj->SetBitangents(vecBiNormals);
	pDataObj->SetTangents  (vecTangents);

	return true;
}