Example #1
0
/*---------------------------------------------------------------------------*/
BSLightingShaderPropertyRef NifConvertUtility::cloneBSLightingShaderProperty(BSLightingShaderPropertyRef pSource)
{
	BSLightingShaderPropertyRef		pDest(new BSLightingShaderProperty);
	BSShaderTextureSetRef			pTSet(pSource->GetTextureSet());

	//  force empty texture set to source (HACK)
	pSource->SetTextureSet(NULL);

	//  copy all members, even inaccessable ones (HACK)
	memcpy(pDest, pSource, sizeof(BSLightingShaderProperty));

	//  reset source texture set
	pSource->SetTextureSet(pTSet);

	return pDest;
}
/*---------------------------------------------------------------------------*/
BSLightingShaderPropertyRef NifConvertUtility::cloneBSLightingShaderProperty(BSLightingShaderPropertyRef pSource)
{
	//BSLightingShaderPropertyRef clone = DynamicCast<BSLightingShaderProperty>(pSource->Clone());
	//return clone;
	//NiExtraDataRef ext_dat = DynamicCast<NiExtraData>(tx_clone);
	

	BSLightingShaderPropertyRef		pDest(new BSLightingShaderProperty);
	BSShaderTextureSetRef			pTSet(pSource->GetTextureSet());

	//  force empty texture set to source (HACK)
	pSource->SetTextureSet(NULL);
	//pTSet->Clone();

	//  copy all members, even inaccessable ones (HACK)
	memcpy(pDest, pSource, sizeof(BSLightingShaderProperty));

	//  reset source texture set
	pSource->SetTextureSet(pTSet);

	return pDest;
}
/*---------------------------------------------------------------------------*/
NiTriShapeRef NifConvertUtility::convertNiTriShape(NiTriShapeRef pSrcNode, NiTriShapeRef pTmplNode, NiAlphaPropertyRef pTmplAlphaProp)
{
	BSLightingShaderPropertyRef	pTmplLShader(NULL);
	BSLightingShaderPropertyRef	pDstLShader (NULL);
	vector<NiPropertyRef>		dstPropList;
	short						bsPropIdx   (0);
	bool						forceAlpha  (pTmplAlphaProp != NULL);
	bool						hasAlpha    (false);

	//  NiTriShape is moved from src to dest. It's unlinked in calling function
	NiTriShapeRef		pDstNode(pSrcNode);
	NiGeometryDataRef	pDstGeo (pDstNode->GetData());

	//  force some data in destination shape
	pDstNode->SetCollisionObject(NULL);  //  no collision object here
	pDstNode->SetFlags          (14);    //  ???

	//  data node
	if (pDstGeo != NULL)
	{
		//  set flags
		if (pTmplNode->GetData() != NULL)
		{
			pDstGeo->SetConsistencyFlags(pTmplNode->GetData()->GetConsistencyFlags());  //  nessessary ???
		}

		//  update tangent space?
		if ((_updateTangentSpace) && (DynamicCast<NiTriShapeData>(pDstGeo) != NULL))
		{
			//  update tangent space
			if (updateTangentSpace(DynamicCast<NiTriShapeData>(pDstGeo)))
			{
				//  enable tangent space
				pDstGeo->SetTspaceFlag(0x10);
			}
		}  //  if (_updateTangentSpace)
	}  //  if (pDstGeo != NULL)

	//  properties - get them from template
	for (short index(0); index < 2; ++index)
	{
		//  BSLightingShaderProperty
		if (DynamicCast<BSLightingShaderProperty>(pTmplNode->GetBSProperty(index)) != NULL)
		{
			pTmplLShader = DynamicCast<BSLightingShaderProperty>(pTmplNode->GetBSProperty(index));
		}
		//  NiAlphaProperty
		else if (DynamicCast<NiAlphaProperty>(pTmplNode->GetBSProperty(index)) != NULL)
		{
			pTmplAlphaProp = DynamicCast<NiAlphaProperty>(pTmplNode->GetBSProperty(index));
		}
	}  //  for (short index(0); index < 2; ++index)

	//  parse properties of destination node
	dstPropList = pDstNode->GetProperties();

	for (vector<NiPropertyRef>::iterator  ppIter = dstPropList.begin(); ppIter != dstPropList.end(); ppIter++)
	{
		//  NiAlphaProperty
		if (DynamicCast<NiAlphaProperty>(*ppIter) != NULL)
		{
			NiAlphaPropertyRef	pPropAlpha(DynamicCast<NiAlphaProperty>(*ppIter));

			//  set values from template
			pPropAlpha->SetFlags        (pTmplAlphaProp->GetFlags());
			pPropAlpha->SetTestThreshold(pTmplAlphaProp->GetTestThreshold());

			//  remove property from node
			pDstNode->RemoveProperty(*ppIter);

			//  set new property to node
			pDstNode->SetBSProperty(bsPropIdx++, &(*pPropAlpha));

			//  own alpha, reset forced alpha
			forceAlpha = false;

			//  mark alpha property
			hasAlpha = true;
		}
		//  NiTexturingProperty
		else if (DynamicCast<NiTexturingProperty>(*ppIter) != NULL)
		{
			char*						pTextPos (NULL);
			BSShaderTextureSetRef		pDstSText(new BSShaderTextureSet());
			TexDesc						baseTex  ((DynamicCast<NiTexturingProperty>(*ppIter))->GetTexture(BASE_MAP));
			char						fileName[1000] = {0};
			char						textName[1000] = {0};

			//  clone shader property from template
			pDstLShader = cloneBSLightingShaderProperty(pTmplLShader);
			//pDstLShader = new BSLightingShaderProperty();

			//  copy textures from template to copy
			pDstSText->SetTextures(pTmplLShader->GetTextureSet()->GetTextures());

			//  set new texture names
			sprintf(fileName, "%s", (const char*) _pathTexture.c_str());
			baseTex.source->GetTextureFileName().copy(textName, 1000, 0);
			pTextPos = strrchr(textName, '\\');
			if (pTextPos == NULL)
			{
				pTextPos = strrchr(textName, '/');
			}
			if (pTextPos != NULL)
			{
				strcat(fileName, ++pTextPos);
			}
			else
			{
				strcat(fileName, textName);
			}
			fileName[strlen(fileName) - 3] = 0;
			strcat(fileName, "dds");

			//  set new texture map
			pDstSText->SetTexture(0, fileName);

			logMessage(NCU_MSG_TYPE_TEXTURE, string("Txt-Used: ") + fileName);
			if (!checkFileExists(fileName))
			{
				_newTextures.insert(string("Txt-Missed: ") + fileName);
			}

			fileName[strlen(fileName) - 4] = 0;
			strcat(fileName, "_n.dds");

			//  set new normal map
			pDstSText->SetTexture(1, fileName);

			if (!checkFileExists(fileName))
			{
				_newTextures.insert(string("Txt-Missed: ") + fileName);
			}

			//  add texture set to texture property
			pDstLShader->SetTextureSet(pDstSText);

			//  check for existing vertex colors
			if ((pDstGeo != NULL) && (pDstGeo->GetColors().size() <= 0) && ((pDstLShader->GetShaderFlags2() & Niflib::SLSF2_VERTEX_COLORS) != 0))
			{
				switch (_vcHandling)
				{
					case NCU_VC_REMOVE_FLAG:
					{
						pDstLShader->SetShaderFlags2((SkyrimShaderPropertyFlags2) (pDstLShader->GetShaderFlags2() & ~Niflib::SLSF2_VERTEX_COLORS));
						break;
					}

					case NCU_VC_ADD_DEFAULT:
					{
						pDstGeo->SetVertexColors(vector<Color4>(pDstGeo->GetVertexCount(), _vcDefaultColor));
						break;
					}
				}
			}  //  if ((pDstGeo != NULL) && (pDstGeo->GetColors().size() <= 0) && ...

			//  remove property from node
			pDstNode->RemoveProperty(*ppIter);

			//  set new property to node
			pDstNode->SetBSProperty(bsPropIdx++, &(*pDstLShader));
		}
		//  NiMaterialProperty
		else if (DynamicCast<NiMaterialProperty>(*ppIter) != NULL)
		{
			//  remove property from node
			pDstNode->RemoveProperty(*ppIter);
		}
	}  //  for (vector<NiPropertyRef>::iterator  ppIter = dstPropList.begin(); ppIter != dstPropList.end(); ppIter++)

	//  add forced NiAlphaProperty?
	if (forceAlpha)
	{
		NiAlphaPropertyRef	pPropAlpha(new NiAlphaProperty());

		//  set values from template
		pPropAlpha->SetFlags        (pTmplAlphaProp->GetFlags());
		pPropAlpha->SetTestThreshold(pTmplAlphaProp->GetTestThreshold());

		//  set new property to node
		pDstNode->SetBSProperty(bsPropIdx++, &(*pPropAlpha));

		//  mark alpha property
		hasAlpha = true;

	}  //  if (forceAlpha)

	//  add default vertex colors if alpha property and no colors
	if (hasAlpha && (pDstGeo != NULL) && (pDstGeo->GetColors().size() <= 0))
	{
		pDstGeo->SetVertexColors(vector<Color4>(pDstGeo->GetVertexCount(), _vcDefaultColor));

		//  force flag in BSLightingShaderProperty
		if (pDstLShader != NULL)
		{
			pDstLShader->SetShaderFlags2((SkyrimShaderPropertyFlags2) (pDstLShader->GetShaderFlags2() | Niflib::SLSF2_VERTEX_COLORS));
		}
	}

	//  reorder properties
	//could be in the inenviable position of neither bsproperties existing
	if (_reorderProperties && pDstNode->GetBSProperty(0) && pDstNode->GetBSProperty(1))
	{
		NiPropertyRef	tProp01(pDstNode->GetBSProperty(0));
		NiPropertyRef	tProp02(pDstNode->GetBSProperty(1));

		//  make sure BSLightingShaderProperty comes before NiAlphaProperty - seems a 'must be'
		if ((tProp01->GetType().GetTypeName() == "NiAlphaProperty") &&
			(tProp02->GetType().GetTypeName() == "BSLightingShaderProperty")
		   )
		{
			pDstNode->SetBSProperty(0, tProp02);
			pDstNode->SetBSProperty(1, tProp01);
		}
	}  //  if (_reorderProperties)

	return  pDstNode;
}
Example #4
0
/*---------------------------------------------------------------------------*/
NiTriShapeRef NifConvertUtility::convertNiTri(NiTriShapeRef pDstNode, NiTriShapeRef pTmplNode, NiAlphaPropertyRef pTmplAlphaProp)
{
	BSLightingShaderPropertyRef			pTmplLShader(NULL);
	BSLightingShaderPropertyRef			pDstLShader (NULL);
	NiGeometryDataRef					pDstGeo     (pDstNode->GetData());
	vector<NiPropertyRef>				dstPropList (pDstNode->GetProperties());
	vector<NiPropertyRef>				dstPropArray;
	list<NiExtraDataRef>				dstExtraList(pDstNode->GetExtraData());
	short								bsPropIdx   (0);
	bool								forceAlpha  (pTmplAlphaProp != NULL);
	bool								hasAlpha    (false);
	bool								tanWasCopied(false);

	//  copy new style properties
	if (pDstNode->GetBSProperty(0) != NULL)		dstPropArray.push_back(pDstNode->GetBSProperty(0));
	if (pDstNode->GetBSProperty(1) != NULL)		dstPropArray.push_back(pDstNode->GetBSProperty(1));

	//  look for tangent space data
	for (auto pIter=dstExtraList.begin(), pEnd=dstExtraList.end(); pIter != pEnd; ++pIter)
	{
		if ((DynamicCast<NiBinaryExtraData>(*pIter) != NULL) && (pDstGeo != NULL))
		{
			vector<byte>	vecByte(DynamicCast<NiBinaryExtraData>(*pIter)->GetData());
			vector<Vector3>	vecTan;
			vector<Vector3>	vecBin;
			float*			pStartT((float*) &(vecByte[0]));
			int				numVert(pDstGeo->GetVertexCount() * 3);

			//  extract tangent space
			for (int i(0); i < numVert; i += 3)
			{
				vecTan.push_back(Vector3(pStartT[i],         pStartT[i+1],         pStartT[i+2]));
				vecBin.push_back(Vector3(pStartT[numVert+i], pStartT[numVert+i+1], pStartT[numVert+i+2]));
			}

			//  set tangent space
			pDstGeo->SetTangents  (vecTan);
			pDstGeo->SetBitangents(vecBin);

			//  enable tangent space
			pDstGeo->SetTspaceFlag(0x10);

			tanWasCopied = true;

		}  //  if ((DynamicCast<NiBinaryExtraData>(*pIter) != NULL) && (pDstGeo != NULL))
	}  //  for (auto pIter=dstExtraList.begin(), pEnd=dstExtraList.end(); pIter != pEnd; ++pIter)

	//  remove extra data
	pDstNode->ClearExtraData();

	//  data node
	if (pDstGeo != NULL)
	{
		//  set flags
		if (pTmplNode->GetData() != NULL)
		{
			pDstGeo->SetConsistencyFlags(pTmplNode->GetData()->GetConsistencyFlags());  //  nessessary ???
		}

		//  update tangent space?
		if (_updateTangentSpace && !tanWasCopied && (DynamicCast<NiTriShapeData>(pDstGeo) != NULL))
		{
			//  update tangent space
			if (updateTangentSpace(DynamicCast<NiTriShapeData>(pDstGeo)))
			{
				//  enable tangent space
				pDstGeo->SetTspaceFlag(0x10);
			}
		}  //  if (_updateTangentSpace)
	}  //  if (pDstGeo != NULL)

	//  properties - get them from template
	for (short index(0); index < 2; ++index)
	{
		//  BSLightingShaderProperty
		if (DynamicCast<BSLightingShaderProperty>(pTmplNode->GetBSProperty(index)) != NULL)
		{
			pTmplLShader = DynamicCast<BSLightingShaderProperty>(pTmplNode->GetBSProperty(index));
		}
		//  NiAlphaProperty
		else if (DynamicCast<NiAlphaProperty>(pTmplNode->GetBSProperty(index)) != NULL)
		{
			pTmplAlphaProp = DynamicCast<NiAlphaProperty>(pTmplNode->GetBSProperty(index));
		}
	}  //  for (short index(0); index < 2; ++index)

	//  parse properties of destination node
	//dstPropList = pDstNode->GetProperties();
	pDstNode->ClearProperties();
	pDstNode->SetBSProperties(Niflib::array<2, NiPropertyRef>());

	for (auto ppIter=dstPropList.begin(), pEnd=dstPropList.end(); ppIter != pEnd; ppIter++)
	{
		//  NiAlphaProperty
		if (DynamicCast<NiAlphaProperty>(*ppIter) != NULL)
		{
			NiAlphaPropertyRef	pPropAlpha(DynamicCast<NiAlphaProperty>(*ppIter));

			//  set new property to node
			pDstNode->SetBSProperty(bsPropIdx++, &(*pPropAlpha));

			//  own alpha, reset forced alpha
			forceAlpha = false;

			//  mark alpha property
			hasAlpha = true;
		}
		//  NiTexturingProperty
		else if (DynamicCast<NiTexturingProperty>(*ppIter) != NULL)
		{
			char*						pTextPos (NULL);
			BSShaderTextureSetRef		pDstSText(new BSShaderTextureSet());
			TexDesc						baseTex  ((DynamicCast<NiTexturingProperty>(*ppIter))->GetTexture(BASE_MAP));
			string						texture  (baseTex.source->GetTextureFileName());
			string::size_type			result   (string::npos);

			//  clone shader property from template
			pDstLShader = cloneBSLightingShaderProperty(pTmplLShader);

			//  copy textures from template to copy
			pDstSText->SetTextures(pTmplLShader->GetTextureSet()->GetTextures());

			//  separate filename from path
			result = texture.rfind('\\');
			if (result == string::npos)			result  = texture.find_last_of('/');
			if (result != string::npos)			texture = texture.substr(result + 1);

			//  build texture name
			if (_forceDDS)
			{
				result = texture.rfind('.');
				if (result != string::npos)		texture.erase(result);
				texture += ".dds";
			}

			//  build full path
			texture = _pathTexture + texture;

			//  set new texture map
			pDstSText->SetTexture(0, texture);

			logMessage(NCU_MSG_TYPE_TEXTURE, string("Txt-Used: ") + texture);
			if (!checkFileExists(texture))
			{
				_newTextures.insert(string("Txt-Missed: ") + texture);
			}

			//  build normal map name
			result = texture.rfind('.');
			if (result == string::npos)
			{
				texture += "_n";
			}
			else
			{
				string	extension(texture.substr(result));

				texture.erase(result);
				texture += "_n" + extension;
			}

			//  set new normal map
			pDstSText->SetTexture(1, texture);

			if (!checkFileExists(texture))
			{
				_newTextures.insert(string("Txt-Missed: ") + texture);
			}

			//  add texture set to texture property
			pDstLShader->SetTextureSet(pDstSText);

			//  check for existing vertex colors
			if ((pDstGeo != NULL) && (pDstGeo->GetColors().size() <= 0) && ((pDstLShader->GetShaderFlags2() & Niflib::SLSF2_VERTEX_COLORS) != 0))
			{
				switch (_vcHandling)
				{
					case NCU_VC_REMOVE_FLAG:
					{
						pDstLShader->SetShaderFlags2((SkyrimShaderPropertyFlags2) (pDstLShader->GetShaderFlags2() & ~Niflib::SLSF2_VERTEX_COLORS));
						break;
					}

					case NCU_VC_ADD_DEFAULT:
					{
						pDstGeo->SetVertexColors(vector<Color4>(pDstGeo->GetVertexCount(), _vcDefaultColor));
						break;
					}
				}
			}  //  if ((pDstGeo != NULL) && (pDstGeo->GetColors().size() <= 0) && ...

			//  set new property to node
			pDstNode->SetBSProperty(bsPropIdx++, &(*pDstLShader));
		}
		//  NiMaterialProperty
		else if (DynamicCast<NiMaterialProperty>(*ppIter) != NULL)
		{
			//  remove property from node
			pDstNode->RemoveProperty(*ppIter);
		}
	}  //  for (vector<NiPropertyRef>::iterator  ppIter = dstPropList.begin(); ppIter != dstPropList.end(); ppIter++)

	//  add forced NiAlphaProperty?
	if (forceAlpha)
	{
		NiAlphaPropertyRef	pPropAlpha(new NiAlphaProperty());

		//  set values from template
		pPropAlpha->SetFlags        (pTmplAlphaProp->GetFlags());
		pPropAlpha->SetTestThreshold(pTmplAlphaProp->GetTestThreshold());

		//  set new property to node
		pDstNode->SetBSProperty(bsPropIdx++, &(*pPropAlpha));

		//  mark alpha property
		hasAlpha = true;

	}  //  if (forceAlpha)

	//  add default vertex colors if alpha property and no colors
	if (hasAlpha && (pDstGeo != NULL) && (pDstGeo->GetColors().size() <= 0))
	{
		pDstGeo->SetVertexColors(vector<Color4>(pDstGeo->GetVertexCount(), _vcDefaultColor));

		//  force flag in BSLightingShaderProperty
		if (pDstLShader != NULL)
		{
			pDstLShader->SetShaderFlags2((SkyrimShaderPropertyFlags2) (pDstLShader->GetShaderFlags2() | Niflib::SLSF2_VERTEX_COLORS));
		}
	}

	//  add allowed properties to fee slots
	for (auto pIter=dstPropArray.begin(), pEnd=dstPropArray.end(); (pIter != pEnd) && (bsPropIdx < 2); ++pIter)
	{
		//  skip old style properties
		if ((*pIter)->GetType().GetTypeName() == "NiMaterialProperty")		continue;

		//  add property to free slot
		pDstNode->SetBSProperty(bsPropIdx++, *pIter);
	}

	//  reorder properties - only necessary in case of both are set
	if (_reorderProperties && (pDstNode->GetBSProperty(0) != NULL) && (pDstNode->GetBSProperty(1) != NULL))
	{
		NiPropertyRef	tProp01(pDstNode->GetBSProperty(0));
		NiPropertyRef	tProp02(pDstNode->GetBSProperty(1));

		//  make sure BSLightingShaderProperty comes before NiAlphaProperty - seems a 'must be'
		if ((tProp01->GetType().GetTypeName() == "NiAlphaProperty") &&
			(tProp02->GetType().GetTypeName() == "BSLightingShaderProperty")
		   )
		{
			pDstNode->SetBSProperty(0, tProp02);
			pDstNode->SetBSProperty(1, tProp01);
		}
	}  //  if (_reorderProperties)

	return  pDstNode;
}
Example #5
0
/*---------------------------------------------------------------------------*/
NiNodeRef NifPrepareUtility::parse4Armor(NiNodeRef pNode, BSLightingShaderPropertyRef pShaderTmpl)
{
	vector<NiAVObjectRef>	childList(pNode->GetChildren());

	//  unlink children
	pNode->ClearChildren();

	//  iterate over children
	for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++)
	{
		//  NiTriShape => remodel BSLightingShaderProperty
		if (DynamicCast<NiTriShape>(*pIter) != NULL)
		{
			NiTriShapeRef				pShape  (DynamicCast<NiTriShape>(*pIter));
			BSDismemberSkinInstanceRef	pSkin   (DynamicCast<BSDismemberSkinInstance>(pShape->GetSkinInstance()));
			vector<NiPropertyRef>		propList(pShape->GetProperties());

			//  part of skin data? => modify skin code
			if (pSkin != NULL)
			{
				vector<BodyPartList>	bPartList(pSkin->GetPartitions());

				for (auto pIter(bPartList.begin()), pEnd(bPartList.end()); pIter != pEnd; pIter++)
				{
					if (_bodyPartMap.count(pIter->bodyPart) > 0)
					{
						pIter->bodyPart = (BSDismemberBodyPartType) _bodyPartMap[pIter->bodyPart];
					}
				}  //  for (auto pIter(bPartList.begin()), pEnd(bPartList.end()); pIter != pEnd; pIter++)

				//  set modified parts
				pSkin->SetPartitions(bPartList);

			}  //  if (pSkin != NULL)

			//  remove all properties
			pShape->ClearProperties();

			//  create new BSLightingShaderProperty if template given
			if (pShaderTmpl != NULL)
			{
				//  check properties
				for (auto pIterProp(propList.begin()), pEnd(propList.end()); pIterProp != pEnd; pIterProp++)
				{
					//  convert BSShaderPPLightingProperty to BSLightingShaderProperty
					if (DynamicCast<BSShaderPPLightingProperty>(*pIterProp) != NULL)
					{
						BSShaderPPLightingProperty*	pPProp(DynamicCast<BSShaderPPLightingProperty>(*pIterProp));
						BSLightingShaderProperty*	pLProp(new BSLightingShaderProperty());

						//  move texture set
						pLProp->SetTextureSet(pPProp->GetTextureSet());
						pPProp->SetTextureSet(NULL);

						pLProp->SetShaderFlags1       (pShaderTmpl->GetShaderFlags1());
						pLProp->SetShaderFlags2       (pShaderTmpl->GetShaderFlags2());
						pLProp->SetEmissiveMultiple   (pShaderTmpl->GetEmissiveMultiple());
						pLProp->SetEmissiveColor      (pShaderTmpl->GetEmissiveColor());
						pLProp->SetLightingEffect1    (pShaderTmpl->GetLightingEffect1());
						pLProp->SetLightingEffect2    (pShaderTmpl->GetLightingEffect2());
						pLProp->SetEnvironmentMapScale(pShaderTmpl->GetEnvironmentMapScale());
						pLProp->SetSkyrimShaderType   (pShaderTmpl->GetSkyrimShaderType());
						pLProp->SetSpecularColor      (pShaderTmpl->GetSpecularColor());
						pLProp->SetSpecularStrength   (pShaderTmpl->GetSpecularStrength());
						pLProp->SetTextureClampMode   (pShaderTmpl->GetTextureClampMode());
						pLProp->SetUnknownFloat2      (pShaderTmpl->GetUnknownFloat2());
						pLProp->SetGlossiness         (pShaderTmpl->GetGlossiness());

						//  add property to shape
						pShape->SetBSProperty(0, pLProp);
					}
				}  //  for (auto pIterProp(propList.begin()), pEnd(propList.end()); pIterProp != pEnd; pIterProp++)
			}  //  if (pShaderTmpl != NULL)

			//  add shape to node
			pNode->AddChild(*pIter);
		}
		//  NiNode (and derived classes?) => iterate subnodes
		else if (DynamicCast<NiNode>(*pIter) != NULL)
		{
			pNode->AddChild(&(*parse4Armor(DynamicCast<NiNode>(*pIter), pShaderTmpl)));
		}
	}  //  for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++)

	return pNode;
}