4 #include "../SiliconStudio.Paradox.Assimp.Translation/Extension.h"
11 using namespace System::Collections;
12 using namespace System::Collections::Generic;
13 using namespace System::Diagnostics;
14 using namespace System::IO;
15 using namespace SiliconStudio;
16 using namespace SiliconStudio::Core;
17 using namespace SiliconStudio::Core::Diagnostics;
18 using namespace SiliconStudio::Core::IO;
19 using namespace SiliconStudio::Core::Mathematics;
20 using namespace SiliconStudio::Core::Serialization;
21 using namespace SiliconStudio::Core::Serialization::Assets;
22 using namespace SiliconStudio::Core::Serialization::Contents;
23 using namespace SiliconStudio::Paradox::Assets::Materials;
24 using namespace SiliconStudio::Paradox::Assets::Materials::Nodes;
25 using namespace SiliconStudio::Paradox::AssimpNet;
26 using namespace SiliconStudio::Paradox::DataModel;
27 using namespace SiliconStudio::Paradox::Engine;
28 using namespace SiliconStudio::Paradox::EntityModel;
29 using namespace SiliconStudio::Paradox::Effects;
30 using namespace SiliconStudio::Paradox::Effects::Data;
31 using namespace SiliconStudio::Paradox::Effects::Modules;
32 using namespace SiliconStudio::Paradox::Extensions;
33 using namespace SiliconStudio::Paradox::Graphics;
34 using namespace SiliconStudio::Paradox::Graphics::Data;
35 using namespace SiliconStudio::Paradox::Shaders;
37 using namespace Assimp;
38 using namespace SiliconStudio::Paradox::Importer::Common;
40 namespace SiliconStudio {
namespace Paradox {
namespace Importer {
namespace AssimpNET {
47 Instances =
gcnew List<MaterialInstanciation^>();
60 HasSkinningPosition =
false;
61 HasSkinningNormal =
false;
62 TotalClusterCount = 0;
66 List<MeshBoneDefinition>^
Bones;
81 Stopwatch^ internalStopwatch;
85 String^ vfsInputFilename;
86 String^ vfsOutputFilename;
90 List<ModelNodeDefinition> nodes;
91 Dictionary<IntPtr, int> nodeMapping;
92 Dictionary<String^, int>^ textureNameCount;
94 List<MeshData^>^ effectMeshes;
95 Dictionary<String^, List<EntityData^ >^ >^ nodeNameToNodeData;
96 Dictionary<IntPtr, EntityData^>^ nodePtrToNodeData;
97 Dictionary<int, List<EntityData^>^ >^ meshIndexToReferingNodes;
102 if(logger ==
nullptr)
103 logger = Core::Diagnostics::GlobalLogger::GetLogger(
"Importer Assimp");
105 internalStopwatch =
gcnew Stopwatch();
111 const aiScene* Initialize(String^ inputFilename, String^ outputFilename, Assimp::Importer* importer,
unsigned int flags)
114 ResetConvertionData();
117 auto splitString = inputFilename->Split(
':');
118 auto unixStyleInputFilename =
"/" + splitString[0] + splitString[1];
120 this->vfsInputFilename = inputFilename;
121 this->vfsOutputFilename = outputFilename;
122 this->vfsInputPath = VirtualFileSystem::GetParentFolder(inputFilename);
124 auto stream = VirtualFileSystem::Drive->OpenStream(unixStyleInputFilename, VirtualFileMode::Open, VirtualFileAccess::Read, VirtualFileShare::Read, StreamFlags::None);
127 if(stream ==
nullptr)
128 throw gcnew ArgumentNullException(
"Input Stream");
136 internalStopwatch->StartNew();
137 auto memoryStream =
gcnew MemoryStream();
138 stream->CopyTo(memoryStream);
139 auto buffer = memoryStream->ToArray();
140 Logger->
Verbose(
"File Stream copied - Time taken: {0} ms.",
nullptr, internalStopwatch->ElapsedMilliseconds);
143 internalStopwatch->StartNew();
144 cli::pin_ptr<System::Byte> bufferStart = &buffer[0];
145 return importer->ReadFileFromMemory(bufferStart, buffer->Length, flags);
149 void ResetConvertionData()
151 effectMeshes =
gcnew List<MeshData^>();
152 nodeNameToNodeData =
gcnew Dictionary<String^, List<EntityData^ >^ >();
153 nodePtrToNodeData =
gcnew Dictionary<IntPtr, EntityData^>();
154 meshIndexToReferingNodes =
gcnew Dictionary<int, List<EntityData^>^ >();
155 textureNameCount =
gcnew Dictionary<String^, int>();
158 void ExtractEmbededTexture(aiTexture* texture)
160 Logger->
Warning(
"The input file contains embeded textures. Embeded textures are not currently supported. This texture will be ignored",
161 gcnew NotImplementedException(
"Embeded textures extraction"),
162 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
165 void NormalizeVertexWeights(std::vector<std::vector<std::pair<short,float> > >& controlPts,
int nbBoneByVertex)
167 for(
unsigned int vertexId=0; vertexId<controlPts.size(); ++vertexId)
169 auto& curVertexWeights = controlPts[vertexId];
172 if((
int) curVertexWeights.size() > nbBoneByVertex)
173 Logger->
Warning(
"The input file contains vertices that are associated to more than {0} bones. In current version of the system, a single vertex can only be associated to {0} bones. Extra bones will be ignored",
174 gcnew ArgumentOutOfRangeException(
"To much bones influencing a single vertex"),
175 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
178 curVertexWeights.resize(nbBoneByVertex, std::pair<short, float>(0, 0.0f));
180 float totalWeight = 0.f;
181 for(
int boneId=0; boneId<nbBoneByVertex; ++boneId)
182 totalWeight += curVertexWeights[boneId].second;
184 if(totalWeight == 0.f)
187 for(
int boneId=0; boneId<nbBoneByVertex; ++boneId)
188 curVertexWeights[boneId].second /= totalWeight;
192 bool IsTransparent(aiMaterial* pMaterial)
195 if(pMaterial->Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS)
196 return (opacity != 1.0);
200 MeshInfo^ ProcessMesh(
const aiScene* scene, aiMesh* mesh, std::map<aiMesh*, std::string>& meshNames)
203 const int nbBonesByVertex = 4;
205 List<MeshBoneDefinition>^ bones =
nullptr;
206 bool hasSkinningPosition =
false;
207 bool hasSkinningNormal =
false;
208 int totalClusterCount = 0;
212 std::vector<std::vector<std::pair<short, float> > > vertexIndexToBoneIdWeight;
215 bones =
gcnew List<MeshBoneDefinition>();
220 vertexIndexToBoneIdWeight.resize(mesh->mNumVertices);
223 for(
unsigned int boneId = 0; boneId < mesh->mNumBones; ++boneId)
225 auto bone = mesh->mBones[boneId];
228 for(
unsigned int vtxWeightId=0; vtxWeightId<bone->mNumWeights; ++vtxWeightId)
230 auto vtxWeight = bone->mWeights[vtxWeightId];
231 vertexIndexToBoneIdWeight[vtxWeight.mVertexId].push_back(std::make_pair(boneId, vtxWeight.mWeight));
236 auto boneName =
gcnew String(bone->mName.C_Str());
237 for (
int nodeDefId = 0; nodeDefId < nodes.Count; ++nodeDefId)
239 auto nodeDef = nodes[nodeDefId];
240 if (nodeDef.Name->Equals(boneName))
242 nodeIndex = nodeDefId;
259 NormalizeVertexWeights(vertexIndexToBoneIdWeight, nbBonesByVertex);
261 totalClusterCount = mesh->mNumBones;
262 if (totalClusterCount > 0)
263 hasSkinningPosition =
true;
267 auto vertexElements =
gcnew List<VertexElement>();
268 int vertexStride = 0;
270 int positionOffset = vertexStride;
271 vertexElements->Add(VertexElement::Position<Vector3>(0, vertexStride));
272 vertexStride +=
sizeof(
Vector3);
274 int normalOffset = vertexStride;
275 if (mesh->HasNormals())
277 vertexElements->Add(VertexElement::Normal<Vector3>(0, vertexStride));
278 vertexStride +=
sizeof(
Vector3);
281 int uvOffset = vertexStride;
282 const int sizeUV =
sizeof(
Vector2);
283 for (
unsigned int uvChannel = 0; uvChannel < mesh->GetNumUVChannels(); ++uvChannel)
285 vertexElements->Add(VertexElement::TextureCoordinate<Vector2>(uvChannel, vertexStride));
286 vertexStride += sizeUV;
289 int colorOffset = vertexStride;
290 const int sizeColor =
sizeof(
Color);
291 for (
unsigned int colorChannel=0; colorChannel< mesh->GetNumColorChannels(); ++colorChannel)
293 vertexElements->Add(VertexElement::Color<Color>(colorChannel, vertexStride));
294 vertexStride += sizeColor;
297 int tangentOffset = vertexStride;
298 if (mesh->HasTangentsAndBitangents())
300 vertexElements->Add(VertexElement::Tangent<Vector3>(0, vertexStride));
301 vertexStride +=
sizeof(
Vector3);
304 int bitangentOffset = vertexStride;
305 if (mesh->HasTangentsAndBitangents())
307 vertexElements->Add(VertexElement::BiTangent<Vector3>(0, vertexStride));
308 vertexStride +=
sizeof(
Vector3);
311 int blendIndicesOffset = vertexStride;
312 bool controlPointIndices16 = (AllowUnsignedBlendIndices && totalClusterCount > 256) || (!AllowUnsignedBlendIndices && totalClusterCount > 128);
313 if (vertexIndexToBoneIdWeight.size() > 0)
315 if (controlPointIndices16)
317 if (AllowUnsignedBlendIndices)
319 vertexElements->Add(
VertexElement(
"BLENDINDICES", 0, PixelFormat::R16G16B16A16_UInt, vertexStride));
320 vertexStride +=
sizeof(
unsigned short) * 4;
324 vertexElements->Add(
VertexElement(
"BLENDINDICES", 0, PixelFormat::R16G16B16A16_SInt, vertexStride));
325 vertexStride +=
sizeof(short) * 4;
330 if (AllowUnsignedBlendIndices)
332 vertexElements->Add(
VertexElement(
"BLENDINDICES", 0, PixelFormat::R8G8B8A8_UInt, vertexStride));
333 vertexStride +=
sizeof(
unsigned char) * 4;
337 vertexElements->Add(
VertexElement(
"BLENDINDICES", 0, PixelFormat::R8G8B8A8_SInt, vertexStride));
338 vertexStride +=
sizeof(char) * 4;
343 int blendWeightOffset = vertexStride;
344 if (vertexIndexToBoneIdWeight.size() > 0)
346 vertexElements->Add(
VertexElement(
"BLENDWEIGHT", 0, PixelFormat::R32G32B32A32_Float, vertexStride));
347 vertexStride +=
sizeof(float) * 4;
351 auto vertexBuffer =
gcnew array<Byte>(vertexStride * mesh->mNumVertices);
352 pin_ptr<Byte> vbPointer = &vertexBuffer[0];
353 for (
unsigned int i = 0; i < mesh->mNumVertices; i++)
357 if (mesh->HasNormals())
360 for (
unsigned int uvChannel = 0; uvChannel < mesh->GetNumUVChannels(); ++uvChannel)
362 auto textureCoord = mesh->mTextureCoords[uvChannel][i];
363 *((
Vector2*)(vbPointer + uvOffset + sizeUV*uvChannel)) =
Vector2(textureCoord.x, textureCoord.y);
366 for (
unsigned int colorChannel=0; colorChannel< mesh->GetNumColorChannels(); ++colorChannel)
369 *((
Color*)(vbPointer + colorOffset + sizeColor*colorChannel)) = color;
372 if (mesh->HasTangentsAndBitangents())
378 if (vertexIndexToBoneIdWeight.size() > 0)
380 for(
int bone=0; bone<nbBonesByVertex; ++bone)
382 if (controlPointIndices16)
384 if (AllowUnsignedBlendIndices)
385 ((
unsigned short*)(vbPointer + blendIndicesOffset))[bone] = (
unsigned short)vertexIndexToBoneIdWeight[i][bone].first;
387 ((
short*)(vbPointer + blendIndicesOffset))[bone] = (short)vertexIndexToBoneIdWeight[i][bone].first;
391 if (AllowUnsignedBlendIndices)
392 ((
unsigned char*)(vbPointer + blendIndicesOffset))[bone] = (
unsigned char)vertexIndexToBoneIdWeight[i][bone].first;
394 ((
char*)(vbPointer + blendIndicesOffset))[bone] = (char)vertexIndexToBoneIdWeight[i][bone].first;
396 ((
float*)(vbPointer + blendWeightOffset))[bone] = vertexIndexToBoneIdWeight[i][bone].second;
399 vbPointer += vertexStride;
403 const int nbIndices = 3 * mesh->mNumFaces;
404 array<Byte>^ indexBuffer;
405 bool is32BitIndex = mesh->mNumVertices > 65535;
407 indexBuffer =
gcnew array<Byte>(
sizeof(
unsigned int) * nbIndices);
409 indexBuffer =
gcnew array<Byte>(
sizeof(
unsigned short) * nbIndices);
411 pin_ptr<Byte> ibPointer = &indexBuffer[0];
412 for (
unsigned int i = 0; i < mesh->mNumFaces; i++)
416 for (
int j = 0; j < 3; ++j)
418 *((
unsigned int*)ibPointer) = mesh->mFaces[i].mIndices[j];
419 ibPointer +=
sizeof(
unsigned int);
424 for (
int j = 0; j < 3; ++j)
426 *((
unsigned short*)ibPointer) = (
unsigned short)(mesh->mFaces[i].mIndices[j]);
427 ibPointer +=
sizeof(
unsigned short);
437 auto vbb =
gcnew List<VertexBufferBindingData^>();
438 vbb->Add(vertexBufferBinding);
439 drawData->VertexBuffers = vbb->ToArray();
440 drawData->IndexBuffer = indexBufferBinding;
441 drawData->PrimitiveType = PrimitiveType::TriangleList;
442 drawData->DrawCount = nbIndices;
444 bool isTransparent = IsTransparent(scene->mMaterials[mesh->mMaterialIndex]);
445 bool sortTransparentMeshes =
true;
446 if (isTransparent && sortTransparentMeshes)
448 PolySortExtensions::SortMeshPolygons(drawData, ViewDirectionForTransparentZSort);
451 auto meshInfo =
gcnew MeshInfo();
452 meshInfo->Draw = drawData;
453 meshInfo->Name =
gcnew String(meshNames[mesh].c_str());
454 meshInfo->Bones = bones;
455 meshInfo->HasSkinningPosition = hasSkinningPosition;
456 meshInfo->HasSkinningNormal = hasSkinningNormal;
457 meshInfo->TotalClusterCount = totalClusterCount;
463 void RegisterNodes(aiNode* fromNode,
int parentIndex, std::map<aiNode*, std::string>& nodeNames, std::map<
int, std::vector<int>*>& meshIndexToNodeIndex)
465 int nodeIndex = nodes.Count;
468 for(
unsigned int m=0; m<fromNode->mNumMeshes; ++m)
470 int meshIndex = fromNode->mMeshes[m];
472 if (meshIndexToNodeIndex.find(meshIndex) == meshIndexToNodeIndex.end())
473 meshIndexToNodeIndex[meshIndex] =
new std::vector<int>();
474 meshIndexToNodeIndex[meshIndex]->push_back(nodeIndex);
478 aiVector3t<float> aiTranslation;
479 aiVector3t<float> aiScaling;
480 aiQuaterniont<float> aiOrientation;
481 fromNode->mTransformation.Decompose(aiScaling, aiOrientation, aiTranslation);
489 if (parentIndex == -1)
494 modelNodeDefinition.
Name =
gcnew String(nodeNames[fromNode].c_str());
495 modelNodeDefinition.
Flags = ModelNodeFlags::Default;
496 nodes.Add(modelNodeDefinition);
499 for(
unsigned int child=0; child<fromNode->mNumChildren; ++child)
501 RegisterNodes(fromNode->mChildren[child], nodeIndex, nodeNames, meshIndexToNodeIndex);
506 void RegisterNodes_old(aiNode* fromNode)
514 for(
unsigned int child=0; child<fromNode->mNumChildren; ++child)
515 RegisterNodes_old(fromNode->mChildren[child]);
518 if(!nodeNameToNodeData->ContainsKey(curNode->Name))
519 nodeNameToNodeData->Add(curNode->Name,
gcnew List<EntityData^>());
520 nodeNameToNodeData[curNode->Name]->Add(curNode);
521 nodePtrToNodeData->Add((IntPtr)fromNode, curNode);
524 for(
unsigned int m=0; m<fromNode->mNumMeshes; ++m)
526 int index = fromNode->mMeshes[m];
527 if(!meshIndexToReferingNodes->ContainsKey(index))
528 meshIndexToReferingNodes->Add(index,
gcnew List<EntityData^>());
529 meshIndexToReferingNodes[index]->Add(curNode);
533 void ProcessCamera(
const aiCamera* assimpCam)
542 if(!(nodeNameToNodeData->ContainsKey(camName)))
544 Logger->
Error(
"The node '{0}' is missing in the node hierarchy. Impossible to properly locate the camera.",
545 gcnew ArgumentException(
"Camera node missing in the node hierarchy"), camName,
546 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
549 auto camNodes = nodeNameToNodeData[camName];
553 camData->NearPlane = assimpCam->mClipPlaneNear;
554 camData->FarPlane = assimpCam->mClipPlaneFar;
555 camData->AspectRatio = assimpCam->mAspect;
556 camData->VerticalFieldOfView = assimpCam->mHorizontalFOV / assimpCam->mAspect;
557 auto camTargetNodeName = camName +
".Target";
558 if(nodeNameToNodeData->ContainsKey(camTargetNodeName))
560 auto camTargetNodes = nodeNameToNodeData[camTargetNodeName];
561 if(camTargetNodes->Count > 1)
563 Logger->
Error(
"The camera target '{0}' has several corresponding nodes in the hierarchy. First correspondance will be used.",
564 gcnew ArgumentException(
"Several camera's node correspondance found"), camTargetNodeName,
565 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
567 Logger->
Error(
"Camera targets are not implemented in current version.",
568 gcnew NotImplementedException(
"Camera targets not implemented"), camTargetNodeName,
569 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
575 camNode->
Components->Add(CameraComponent::Key, camData);
578 void ProcessLight(
const aiLight* assimpLight)
587 if(!(nodeNameToNodeData->ContainsKey(lightName)))
589 Logger->
Error(
"The node '{0}' is missing in the node hierarchy. Impossible to properly locate the light.",
590 gcnew ArgumentException(
"Light node missing in the node hierarchy"), lightName,
591 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
594 auto lightNodes = nodeNameToNodeData[lightName];
598 lightData->LightDirection =
Vector3(assimpLight->mDirection.x, assimpLight->mDirection.y, assimpLight->mDirection.z);
604 lightData->Intensity = 1.f;
605 lightData->DecayStart = 1.f;
608 lightData->Layers = RenderLayers::RenderLayerAll;
611 for each (
EntityData^ lightNode
in lightNodes)
612 lightNode->
Components->Add(LightComponent::Key, lightData);
615 void ProcessAnimationCurveVector(
AnimationClip^ animationClip,
const aiVectorKey* keys,
unsigned int nbKeys, String^ partialTargetName,
double ticksPerSec)
624 for(
unsigned int keyId=0; keyId<nbKeys; ++keyId)
626 auto aiKey = keys[keyId];
627 KeyFrameData<Vector3> key;
635 key.Value.X = value.X;
636 key.Value.Y = value.Y;
637 key.Value.Z = value.Z;
639 animationCurve->KeyFrames->Add(key);
640 if(keyId == 0 || keyId == nbKeys-1)
641 animationCurve->KeyFrames->Add(key);
644 animationClip->
AddCurve(partialTargetName, animationCurve);
648 if (animationClip->
Duration < lastKeyTime)
649 animationClip->
Duration = lastKeyTime;
653 void ProcessAnimationCurveQuaternion(
AnimationClip^ animationClip,
const aiQuatKey* keys,
unsigned int nbKeys, String^ partialTargetName,
double ticksPerSec)
659 for(
unsigned int keyId=0; keyId<nbKeys; ++keyId)
661 auto aiKey = keys[keyId];
662 KeyFrameData<Quaternion> key;
670 key.Value.X = value.X;
671 key.Value.Y = value.Y;
672 key.Value.Z = value.Z;
673 key.Value.W = value.W;
675 animationCurve->KeyFrames->Add(key);
678 animationClip->
AddCurve(partialTargetName, animationCurve);
682 if (animationClip->
Duration < lastKeyTime)
683 animationClip->
Duration = lastKeyTime;
687 void ProcessNodeAnimation(
AnimationClip^ animationClip,
const aiNodeAnim* nodeAnim,
double ticksPerSec)
693 ProcessAnimationCurveVector(animationClip, nodeAnim->mScalingKeys, nodeAnim->mNumScalingKeys, String::Format(
"Transformation.Scaling[{0}]", nodeName), ticksPerSec);
695 ProcessAnimationCurveQuaternion(animationClip, nodeAnim->mRotationKeys, nodeAnim->mNumRotationKeys, String::Format(
"Transformation.Rotation[{0}]", nodeName), ticksPerSec);
697 ProcessAnimationCurveVector(animationClip, nodeAnim->mPositionKeys, nodeAnim->mNumPositionKeys, String::Format(
"Transformation.Translation[{0}]", nodeName), ticksPerSec);
703 std::set<std::string> visitedNodeNames;
705 for (
unsigned int i = 0; i < scene->mNumAnimations; ++i)
707 auto aiAnim = scene->mAnimations[i];
716 auto ticksPerSec = aiAnim->mTicksPerSecond;
719 for(
unsigned int meshAnimId = 0; meshAnimId<aiAnim->mNumMeshChannels; ++meshAnimId)
722 Logger->
Warning(
"Mesh animation are not currently supported. Animation '{0}' on mesh {1} will be ignored", animName, meshName,
723 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
727 for(
unsigned int nodeAnimId=0; nodeAnimId<aiAnim->mNumChannels; ++nodeAnimId)
729 auto nodeAnim = aiAnim->mChannels[nodeAnimId];
730 auto nodeName = std::string(nodeAnim->mNodeName.C_Str());
731 if (visitedNodeNames.find(nodeName) == visitedNodeNames.end())
733 visitedNodeNames.insert(nodeName);
734 ProcessNodeAnimation(animationClip, nodeAnim, ticksPerSec);
738 Logger->
Error(
"Animation '{0}' uses two nodes with the same name ({1}). The animation cannot be resolved.", animName,
aiStringToString(nodeAnim->mNodeName),
739 CallerInfo::Get(__FILEW__, __FUNCTIONW__, __LINE__));
744 return animationClip;
750 auto textureValue = TextureLayerGenerator::GenerateMaterialTextureNode(vfsOutputPath, sourceTextureFile, textureUVSetIndex, textureUVscaling, wrapTextureU, wrapTextureV,
Logger);
751 auto referenceName = textureValue->TextureName;
754 if (!textureNameCount->ContainsKey(referenceName))
755 textureNameCount->Add(referenceName, 1);
758 int count = textureNameCount[referenceName];
759 textureNameCount[referenceName] = count + 1;
760 referenceName = String::Concat(referenceName,
"_", count);
764 finalMaterial->
AddNode(referenceName, textureValue);
766 return materialReference;
771 AssimpNet::Material::Stack^ stack = NetTranslation::Materials::convertAssimpStackCppToCs(pMat, textureType);
773 System::Collections::Stack^ compositionFathers =
gcnew System::Collections::Stack();
774 std::stack<int> sets;
777 auto nbTextures = pMat->GetTextureCount(textureType);
778 MaterialNodeBase^ curComposition =
nullptr,^ newCompositionFather =
nullptr;
781 bool isRootElement =
true;
784 while (!stack->IsEmpty)
786 auto top = stack->Pop();
790 if (compositionFathers->Count == 0)
791 Logger->
Error(String::Format(
"Texture Stack Invalid : Operand without Operation."));
798 auto type = top->type;
799 auto strength = top->blend;
800 auto alpha = top->alpha;
804 auto realTop = (AssimpNet::Material::StackOperation^) top;
806 auto binNode =
gcnew MaterialBinaryNode(
nullptr,
nullptr, MaterialBinaryOperand::Add);
810 case AssimpNet::Material::Operation::Add3ds:
811 case AssimpNet::Material::Operation::AddMaya:
812 binNode->Operand = MaterialBinaryOperand::Add;
814 case AssimpNet::Material::Operation::Multiply3ds:
815 case AssimpNet::Material::Operation::MultiplyMaya:
816 binNode->Operand = MaterialBinaryOperand::Multiply;
819 binNode->Operand = MaterialBinaryOperand::Add;
823 curComposition = binNode;
827 auto realTop = (AssimpNet::Material::StackColor^)top;
828 Color3 col = realTop->color;
831 else if (type == AssimpNet::Material::StackType::Texture)
833 auto realTop = (AssimpNet::Material::StackTexture^)top;
834 String ^texPath = realTop->texturePath;
835 int indexUV = realTop->channel;
836 auto textureValue = GetTextureReferenceNode(vfsOutputFilename, texPath, indexUV, Vector2::One,
false,
false, finalMaterial,
Logger);
837 curComposition = textureValue;
840 newCompositionFather = curComposition;
844 float strengthAlpha = strength;
846 strengthAlpha *= alpha;
850 curComposition =
gcnew MaterialBinaryNode(curComposition, factorComposition, MaterialBinaryOperand::Multiply);
855 curComposition =
gcnew MaterialBinaryNode(curComposition, factorComposition, MaterialBinaryOperand::Multiply);
860 rootMaterial = curComposition;
861 isRootElement =
false;
862 compositionFathers->Push(curCompositionFather);
869 compositionFathers->Push(curCompositionFather);
878 Logger->
Error(String::Format(
"Texture Stack Invalid : Invalid Operand Number {0}.", set));
884 compositionFathers->Push(newCompositionFather);
894 auto nbTextures = pMat->GetTextureCount(textureType);
901 colorNode->AutoAssignKey =
false;
902 colorNode->IsReducible =
false;
903 if (textureType == aiTextureType_DIFFUSE)
905 colorNode->Key = MaterialKeys::DiffuseColorValue;
906 finalMaterial->
AddColorNode(MaterialParameters::AlbedoDiffuse,
"diffuse", colorNode);
908 else if (textureType == aiTextureType_SPECULAR)
910 colorNode->Key = MaterialKeys::SpecularColorValue;
911 finalMaterial->
AddColorNode(MaterialParameters::AlbedoSpecular,
"specular", colorNode);
913 else if (textureType == aiTextureType_EMISSIVE)
915 colorNode->Key = MaterialKeys::EmissiveColorValue;
916 finalMaterial->
AddColorNode(MaterialParameters::EmissiveMap,
"emissive", colorNode);
918 else if (textureType == aiTextureType_AMBIENT)
920 colorNode->Key = MaterialKeys::AmbientColorValue;
921 finalMaterial->
AddColorNode(MaterialParameters::AmbientMap,
"ambient", colorNode);
923 else if (textureType == aiTextureType_REFLECTION)
925 colorNode->Key = MaterialKeys::ReflectionColorValue;
926 finalMaterial->
AddColorNode(MaterialParameters::ReflectionMap,
"reflectionMap", colorNode);
929 else if (hasBaseValue)
932 floatNode->AutoAssignKey =
false;
933 floatNode->IsReducible =
false;
934 if (textureType == aiTextureType_OPACITY)
936 floatNode->Key = MaterialKeys::TransparencyValue;
937 finalMaterial->
AddColorNode(MaterialParameters::TransparencyMap,
"transparencyMap", floatNode);
939 else if (textureType == aiTextureType_SHININESS)
941 floatNode->Key = MaterialKeys::SpecularPower;
942 finalMaterial->
AddColorNode(MaterialParameters::SpecularPowerMap,
"specularPower", floatNode);
948 int textureCount = 0;
949 auto albedoNode = GenerateOneTextureTypeLayers(pMat, textureType, textureCount, finalMaterial);
950 if (albedoNode !=
nullptr)
952 if (textureType == aiTextureType_DIFFUSE)
954 if (pMat->GetTextureCount(aiTextureType_LIGHTMAP) > 0)
956 auto lightMap = GenerateOneTextureTypeLayers(pMat, aiTextureType_LIGHTMAP, textureCount, finalMaterial);
957 if (lightMap !=
nullptr)
958 albedoNode =
gcnew MaterialBinaryNode(albedoNode, lightMap, MaterialBinaryOperand::Add);
960 finalMaterial->
AddColorNode(MaterialParameters::AlbedoDiffuse,
"diffuse", albedoNode);
962 else if (textureType == aiTextureType_SPECULAR)
964 finalMaterial->
AddColorNode(MaterialParameters::AlbedoSpecular,
"specular", albedoNode);
966 else if (textureType == aiTextureType_NORMALS)
968 finalMaterial->
AddColorNode(MaterialParameters::NormalMap,
"normalMap", albedoNode);
970 else if (textureType == aiTextureType_DISPLACEMENT)
972 finalMaterial->
AddColorNode(MaterialParameters::DisplacementMap,
"displacementMap", albedoNode);
974 else if (textureType == aiTextureType_AMBIENT)
976 finalMaterial->
AddColorNode(MaterialParameters::AmbientMap,
"ambient", albedoNode);
978 else if (textureType == aiTextureType_OPACITY)
980 finalMaterial->
AddColorNode(MaterialParameters::TransparencyMap,
"transparencyMap", albedoNode);
982 else if (textureType == aiTextureType_SHININESS)
984 finalMaterial->
AddColorNode(MaterialParameters::SpecularPowerMap,
"specularPower", albedoNode);
986 else if (textureType == aiTextureType_EMISSIVE)
988 finalMaterial->
AddColorNode(MaterialParameters::EmissiveMap,
"emissive", albedoNode);
990 else if (textureType == aiTextureType_HEIGHT)
992 finalMaterial->
AddColorNode(MaterialParameters::BumpMap,
"bumpMap", albedoNode);
994 else if (textureType == aiTextureType_REFLECTION)
996 finalMaterial->
AddColorNode(MaterialParameters::ReflectionMap,
"reflectionMap", albedoNode);
1007 float specIntensity;
1008 if (AI_SUCCESS == pMaterial->Get(AI_MATKEY_SHININESS_STRENGTH, specIntensity))
1010 if (specIntensity > 0)
1013 specularIntensityMap->Key = MaterialKeys::SpecularIntensity;
1014 specularIntensityMap->AutoAssignKey =
false;
1015 specularIntensityMap->IsReducible =
false;
1016 finalMaterial->
AddColorNode(MaterialParameters::SpecularIntensityMap,
"specularIntensity", specularIntensityMap);
1024 for(
unsigned int i = 0; i<pMaterial->mNumProperties; ++i)
1026 auto pProp = pMaterial->mProperties[i];
1028 if (propertyName->StartsWith(
"PX_"))
1030 int index = propertyName->IndexOf(
'_');
1031 propertyName = propertyName->Substring(index);
1032 propertyName = propertyName->Replace(
'_',
'.');
1034 propertyName =
gcnew String(
"SiliconStudio.Paradox.Effects.Modules") + propertyName;
1036 switch (pProp->mDataLength)
1038 case sizeof(double):
1040 auto value = *((
double*)pProp->mData);
1045 case 3*
sizeof(double):
1047 auto value = (
double*)pProp->mData;
1049 finalMaterial->
SetParameter(key,
Vector3((
float)value[0], (
float)value[1], (
float)value[2]));
1053 Console::WriteLine(
"Warning, Type for property [{0}] is not supported", propertyName);
1070 bool hasDiffColor =
false;
1071 bool hasSpecColor =
false;
1072 bool hasAmbientColor =
false;
1073 bool hasEmissiveColor =
false;
1074 bool hasReflectiveColor =
false;
1075 bool hasSpecPower =
false;
1076 bool hasOpacity =
false;
1078 if(pMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS)
1081 hasDiffColor =
true;
1083 if(pMaterial->Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS && IsNotBlackColor(color))
1086 hasSpecColor =
true;
1088 if(pMaterial->Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS && IsNotBlackColor(color))
1091 hasAmbientColor =
true;
1093 if(pMaterial->Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS && IsNotBlackColor(color))
1096 hasEmissiveColor =
true;
1098 if(pMaterial->Get(AI_MATKEY_COLOR_REFLECTIVE, color) == AI_SUCCESS && IsNotBlackColor(color))
1101 hasReflectiveColor =
true;
1104 hasSpecPower = (AI_SUCCESS == pMaterial->Get(AI_MATKEY_SHININESS, specPower) && specPower > 0);
1105 if(pMaterial->Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS && opacity < 1.0)
1107 finalMaterial->
SetParameter(MaterialParameters::UseTransparent,
true);
1111 BuildLayeredSurface(pMaterial, hasDiffColor,
false, diffColor, 0.0f, aiTextureType_DIFFUSE, finalMaterial);
1112 BuildLayeredSurface(pMaterial, hasSpecColor,
false, specColor, 0.0f, aiTextureType_SPECULAR, finalMaterial);
1113 BuildLayeredSurface(pMaterial,
false,
false, dummyColor, 0.0f, aiTextureType_NORMALS, finalMaterial);
1114 BuildLayeredSurface(pMaterial,
false,
false, dummyColor, 0.0f, aiTextureType_DISPLACEMENT, finalMaterial);
1115 BuildLayeredSurface(pMaterial, hasAmbientColor,
false, ambientColor, 0.0f, aiTextureType_AMBIENT, finalMaterial);
1116 BuildLayeredSurface(pMaterial,
false, hasOpacity, dummyColor, opacity, aiTextureType_OPACITY, finalMaterial);
1117 BuildLayeredSurface(pMaterial,
false, hasSpecPower, dummyColor, specPower, aiTextureType_SHININESS, finalMaterial);
1118 BuildLayeredSurface(pMaterial, hasEmissiveColor,
false, emissiveColor, 0.0f, aiTextureType_EMISSIVE, finalMaterial);
1119 BuildLayeredSurface(pMaterial,
false,
false, dummyColor, 0.0f, aiTextureType_HEIGHT, finalMaterial);
1120 BuildLayeredSurface(pMaterial, hasReflectiveColor,
false, reflectiveColor, 0.0f, aiTextureType_REFLECTION, finalMaterial);
1122 return finalMaterial;
1125 bool IsNotBlackColor(aiColor3D color)
1127 return color.r != 0 || color.g != 0 || color.b != 0;
1131 void GenerateUniqueNames(std::map<T*, std::string>& finalNames, std::vector<std::string>& baseNames, T** objectsToName)
1133 std::map<std::string, int> itemNameTotalCount;
1134 std::map<std::string, int> itemNameCurrentCount;
1135 std::vector<std::string> tempNames;
1137 for (
int i = 0; i < baseNames.size(); ++i)
1140 T* lItem = objectsToName[i];
1141 std::string itemName = baseNames[i];
1143 auto itemPart = std::string();
1145 int itemNameSplitPosition = itemName.find(
'#');
1146 if (itemNameSplitPosition != std::string::npos)
1148 itemPart = itemName.substr(itemNameSplitPosition + 1);
1149 itemName = itemName.substr(0, itemNameSplitPosition);
1152 itemNameSplitPosition = itemNameSplitPosition = itemName.find(
"__");
1153 if (itemNameSplitPosition != std::string::npos)
1155 itemPart = itemName.substr(itemNameSplitPosition + 2);
1156 itemName = itemName.substr(0, itemNameSplitPosition);
1160 int nextCharacterPos = itemName.find(
':');
1161 while (nextCharacterPos != std::string::npos)
1163 itemName.replace(nextCharacterPos, 1, 1,
'_');
1164 nextCharacterPos = itemName.find(
':', nextCharacterPos);
1166 tempNames.push_back(itemName);
1169 if (itemNameTotalCount.count(itemName) == 0)
1170 itemNameTotalCount[itemName] = 1;
1172 itemNameTotalCount[itemName] = itemNameTotalCount[itemName] + 1;
1175 for (
int i = 0; i < baseNames.size(); ++i)
1177 T* lItem = objectsToName[i];
1178 auto itemName = tempNames[i];
1179 int currentCount = 0;
1181 if (itemNameTotalCount[itemName] > 1)
1183 if (itemNameCurrentCount.count(itemName) == 0)
1184 itemNameCurrentCount[itemName] = 1;
1186 itemNameCurrentCount[itemName] = itemNameCurrentCount[itemName] + 1;
1188 itemName = itemName +
"_" + std::to_string(itemNameCurrentCount[itemName]);
1191 finalNames[lItem] = itemName;
1195 void GenerateMaterialNames(
const aiScene* scene, std::map<aiMaterial*, std::string>& materialNames)
1197 std::vector<std::string> baseNames;
1198 for (uint32_t i = 0; i < scene->mNumMaterials; i++)
1200 auto lMaterial = scene->mMaterials[i];
1202 std::string materialName =
"";
1204 if (lMaterial->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS)
1205 materialName = std::string(aiName.C_Str());
1206 baseNames.push_back(materialName);
1209 GenerateUniqueNames(materialNames, baseNames, scene->mMaterials);
1212 void GenerateMeshNames(
const aiScene* scene, std::map<aiMesh*, std::string>& meshNames)
1214 std::vector<std::string> baseNames;
1215 for (uint32_t i = 0; i < scene->mNumMeshes; i++)
1217 auto lMesh = scene->mMeshes[i];
1218 std::string meshName = std::string(lMesh->mName.C_Str());
1219 baseNames.push_back(meshName);
1222 GenerateUniqueNames(meshNames, baseNames, scene->mMeshes);
1225 void GenerateAnimationNames(
const aiScene* scene, std::map<aiAnimation*, std::string>& animationNames)
1227 std::vector<std::string> baseNames;
1228 for (uint32_t i = 0; i < scene->mNumAnimations; i++)
1230 auto lAnimation = scene->mAnimations[i];
1231 std::string animationName = std::string(lAnimation->mName.C_Str());
1232 baseNames.push_back(animationName);
1235 GenerateUniqueNames(animationNames, baseNames, scene->mAnimations);
1238 void GetNodeNames(aiNode* node, std::vector<std::string>& nodeNames, std::vector<aiNode*>& orderedNodes)
1240 nodeNames.push_back(std::string(node->mName.C_Str()));
1241 orderedNodes.push_back(node);
1242 for (uint32_t i = 0; i < node->mNumChildren; ++i)
1243 GetNodeNames(node->mChildren[i], nodeNames, orderedNodes);
1246 void GenerateNodeNames(
const aiScene* scene, std::map<aiNode*, std::string>& nodeNames)
1248 std::vector<std::string> baseNames;
1249 std::vector<aiNode*> orderedNodes;
1250 GetNodeNames(scene->mRootNode, baseNames, orderedNodes);
1253 int nodeCount = orderedNodes.size();
1254 aiNode** nodeArray =
new aiNode*[nodeCount];
1255 for (
int i = 0; i < nodeCount; ++i)
1256 nodeArray[i] = orderedNodes[i];
1258 GenerateUniqueNames(nodeNames, baseNames, nodeArray);
1263 List<String^>^ ExtractTextureDependencies(
const aiScene *scene)
1265 auto textureNames =
gcnew List<String^>();
1283 std::vector<aiTextureType> allTextureTypes;
1284 allTextureTypes.push_back(aiTextureType_DIFFUSE);
1285 allTextureTypes.push_back(aiTextureType_SPECULAR);
1286 allTextureTypes.push_back(aiTextureType_AMBIENT);
1287 allTextureTypes.push_back(aiTextureType_EMISSIVE);
1288 allTextureTypes.push_back(aiTextureType_HEIGHT);
1289 allTextureTypes.push_back(aiTextureType_NORMALS);
1290 allTextureTypes.push_back(aiTextureType_SHININESS);
1291 allTextureTypes.push_back(aiTextureType_OPACITY);
1292 allTextureTypes.push_back(aiTextureType_DISPLACEMENT);
1293 allTextureTypes.push_back(aiTextureType_LIGHTMAP);
1294 allTextureTypes.push_back(aiTextureType_REFLECTION);
1298 for (uint32_t i = 0; i < scene->mNumMaterials; i++)
1300 for (std::vector<aiTextureType>::iterator it = allTextureTypes.begin(); it != allTextureTypes.end(); ++it)
1302 auto lMaterial = scene->mMaterials[i];
1303 auto nbTextures = lMaterial->GetTextureCount(*it);
1304 for (uint32_t j = 0; j < nbTextures; ++j)
1307 aiTextureMapping mapping;
1310 aiTextureOp textureOp;
1311 aiTextureMapMode mapMode;
1312 if (AI_SUCCESS == lMaterial->GetTexture(*it, 0, &path, &mapping, &index, &blend, &textureOp, &mapMode))
1314 auto relFileName =
gcnew String(path.C_Str());
1315 String^ fileNameToUse = Path::Combine(vfsInputPath, relFileName);
1316 textureNames->Add(fileNameToUse);
1323 return textureNames;
1326 Dictionary<String^, MaterialDescription^>^ ExtractMaterials(
const aiScene *scene, std::map<aiMaterial*, std::string>& materialNames)
1328 GenerateMaterialNames(scene, materialNames);
1330 auto materials =
gcnew Dictionary<String^, MaterialDescription^>();
1331 for (uint32_t i = 0; i < scene->mNumMaterials; i++)
1333 std::map<std::string, int> dict;
1334 auto lMaterial = scene->mMaterials[i];
1335 auto materialName = materialNames[lMaterial];
1336 materials->Add(
gcnew String(materialName.c_str()), ProcessMeshMaterial(lMaterial));
1341 String^ SearchMeshNode(aiNode* node,
unsigned int meshIndex, std::map<aiNode*, std::string>& nodeNames)
1343 for (uint32_t i = 0; i < node->mNumMeshes; ++i)
1345 if (node->mMeshes[i] == meshIndex)
1346 return gcnew String(nodeNames[node].c_str());
1349 for (uint32_t i = 0; i < node->mNumChildren; ++i)
1351 auto res = SearchMeshNode(node->mChildren[i], meshIndex, nodeNames);
1359 List<CameraInfo^>^ ExtractCameras(
const aiScene* scene, std::map<aiNode*, std::string>& nodeNames)
1361 auto allCameras =
gcnew List<CameraInfo^>();
1362 for (uint32_t cameraIndex = 0; cameraIndex < scene->mNumCameras; ++cameraIndex)
1364 auto assimpCam = scene->mCameras[cameraIndex];
1369 auto camName = std::string(assimpCam->mName.C_Str());
1370 bool foundNode =
false;
1371 bool foundTargetNode =
false;
1372 for (std::map<aiNode*, std::string>::iterator iter = nodeNames.begin(); iter != nodeNames.end(); ++iter)
1374 if (camName == iter->second)
1384 cameraInfo->NodeName =
gcnew String(assimpCam->mName.C_Str());
1385 cameraInfo->TargetNodeName = cameraInfo->NodeName +
".Target";
1389 camData->NearPlane = assimpCam->mClipPlaneNear;
1390 camData->FarPlane = assimpCam->mClipPlaneFar;
1391 camData->AspectRatio = assimpCam->mAspect;
1392 camData->VerticalFieldOfView = assimpCam->mHorizontalFOV / assimpCam->mAspect;
1395 cameraInfo->Data = camData;
1396 allCameras->Add(cameraInfo);
1401 List<LightInfo^>^ ExtractLights(
const aiScene* scene, std::map<aiNode*, std::string>& nodeNames)
1403 auto allLights =
gcnew List<LightInfo^>();
1404 for (uint32_t lightIndex = 0; lightIndex < scene->mNumLights; ++lightIndex)
1406 auto assimpLight = scene->mLights[lightIndex];
1411 auto lightName = std::string(assimpLight->mName.C_Str());
1412 bool foundNode =
false;
1413 bool foundTargetNode =
false;
1414 for (std::map<aiNode*, std::string>::iterator iter = nodeNames.begin(); iter != nodeNames.end(); ++iter)
1416 if (lightName == iter->second)
1426 lightInfo->NodeName =
gcnew String(assimpLight->mName.C_Str());
1430 lightData->LightDirection =
Vector3(assimpLight->mDirection.x, assimpLight->mDirection.y, assimpLight->mDirection.z);
1436 lightData->Intensity = 1.f;
1437 lightData->DecayStart = 1.f;
1440 lightData->Layers = RenderLayers::RenderLayerAll;
1442 lightInfo->Data = lightData;
1443 allLights->Add(lightInfo);
1448 List<MeshParameters^>^ ExtractModel(
const aiScene* scene, std::map<aiMesh*, std::string>& meshNames, std::map<aiMaterial*, std::string>& materialNames, std::map<aiNode*, std::string>& nodeNames)
1450 GenerateMeshNames(scene, meshNames);
1452 auto meshList =
gcnew List<MeshParameters^>();
1453 for (uint32_t i = 0; i < scene->mNumMeshes; ++i)
1455 auto mesh = scene->mMeshes[i];
1457 meshParams->MeshName =
gcnew String(meshNames[mesh].c_str());
1458 auto lMaterial = scene->mMaterials[mesh->mMaterialIndex];
1459 meshParams->MaterialName =
gcnew String(materialNames[lMaterial].c_str());
1460 meshParams->NodeName = SearchMeshNode(scene->mRootNode, i, nodeNames);
1461 meshList->Add(meshParams);
1466 List<String^>^ ExtractAnimations(
const aiScene* scene, std::map<aiAnimation*, std::string>& animationNames)
1468 if (scene->mNumAnimations == 0)
1471 GenerateAnimationNames(scene, animationNames);
1473 auto animationList =
gcnew List<String^>();
1474 for (std::map<aiAnimation*, std::string>::iterator it = animationNames.begin(); it != animationNames.end(); ++it)
1476 animationList->Add(
gcnew String(it->second.c_str()));
1478 return animationList;
1481 ModelData^ ConvertAssimpScene(
const aiScene *scene)
1486 std::map<aiMesh*, std::string> meshNames;
1487 GenerateMeshNames(scene, meshNames);
1489 std::map<aiNode*, std::string> nodeNames;
1490 GenerateNodeNames(scene, nodeNames);
1493 std::map<int, std::vector<int>*> meshIndexToNodeIndex;
1495 RegisterNodes(scene->mRootNode, -1, nodeNames, meshIndexToNodeIndex);
1496 modelData->Hierarchy->Nodes = nodes.ToArray();
1499 for (
unsigned int i = 0; i < scene->mNumMeshes; ++i)
1501 if (meshIndexToNodeIndex.find(i) != meshIndexToNodeIndex.end())
1503 auto meshInfo = ProcessMesh(scene, scene->mMeshes[i], meshNames);
1505 for (std::vector<int>::iterator nodeIndexPtr = meshIndexToNodeIndex[i]->begin(); nodeIndexPtr != meshIndexToNodeIndex[i]->end(); ++nodeIndexPtr)
1507 auto nodeMeshData =
gcnew MeshData();
1508 nodeMeshData->Draw = meshInfo->Draw;
1509 nodeMeshData->Name = meshInfo->Name;
1510 nodeMeshData->NodeIndex = *nodeIndexPtr;
1512 if (meshInfo->Bones !=
nullptr)
1515 nodeMeshData->Skinning->Bones = meshInfo->Bones->ToArray();
1517 if (meshInfo->HasSkinningPosition || meshInfo->HasSkinningNormal || meshInfo->TotalClusterCount > 0)
1520 if (meshInfo->HasSkinningPosition)
1521 nodeMeshData->Parameters->Set(MaterialParameters::HasSkinningPosition,
true);
1522 if (meshInfo->HasSkinningNormal)
1523 nodeMeshData->Parameters->Set(MaterialParameters::HasSkinningNormal,
true);
1524 if (meshInfo->TotalClusterCount > 0)
1525 nodeMeshData->Parameters->Set(MaterialParameters::SkinningBones, meshInfo->TotalClusterCount);
1527 modelData->Meshes->Add(nodeMeshData);
1533 for (std::map<
int, std::vector<int>*>::iterator it = meshIndexToNodeIndex.begin(); it != meshIndexToNodeIndex.end(); ++it)
1540 for (
unsigned int i = 0; i < scene->mNumTextures; ++i)
1541 ExtractEmbededTexture(scene->mTextures[i]);
1554 void GetNodes(aiNode* node,
int depth, std::map<aiNode*, std::string>& nodeNames, List<NodeInfo^>^ allNodes)
1556 auto currentIndex = allNodes->Count;
1557 auto newNodeInfo =
gcnew NodeInfo();
1558 newNodeInfo->Name =
gcnew String(nodeNames[node].c_str());
1559 newNodeInfo->Depth = depth;
1560 newNodeInfo->Preserve =
false;
1562 allNodes->Add(newNodeInfo);
1563 for (uint32_t i = 0; i < node->mNumChildren; ++i)
1564 GetNodes(node->mChildren[i], depth + 1, nodeNames, allNodes);
1567 Vector3 GetUpAxis(aiNode* rootNode)
1572 aiVector3t<float> aiTranslation;
1573 aiVector3t<float> aiScaling;
1574 aiQuaterniont<float> aiOrientation;
1575 rootNode->mTransformation.Decompose(aiScaling, aiOrientation, aiTranslation);
1576 if (aiOrientation.x != 0)
1577 return Vector3::UnitZ;
1578 if (aiOrientation.z != 0)
1579 return Vector3::UnitX;
1580 return Vector3::UnitY;
1582 return Vector3::UnitZ;
1585 List<NodeInfo^>^ ExtractNodeHierarchy(
const aiScene *scene, std::map<aiNode*, std::string>& nodeNames)
1587 auto allNodes =
gcnew List<NodeInfo^>();
1588 GetNodes(scene->mRootNode, 0, nodeNames, allNodes);
1599 Assimp::Importer importer;
1600 auto scene = Initialize(inputFilename, outputFilename, &importer,
1601 aiProcess_SortByPType
1602 | aiProcess_RemoveRedundantMaterials);
1604 std::map<aiMaterial*, std::string> materialNames;
1605 std::map<aiMesh*, std::string> meshNames;
1606 std::map<aiAnimation*, std::string> animationNames;
1607 std::map<aiNode*, std::string> nodeNames;
1609 GenerateNodeNames(scene, nodeNames);
1612 entityInfo->TextureDependencies = ExtractTextureDependencies(scene);
1613 entityInfo->Materials = ExtractMaterials(scene, materialNames);
1614 entityInfo->Models = ExtractModel(scene, meshNames, materialNames, nodeNames);
1615 entityInfo->Lights = ExtractLights(scene, nodeNames);
1616 entityInfo->Cameras = ExtractCameras(scene, nodeNames);
1617 entityInfo->Nodes = ExtractNodeHierarchy(scene, nodeNames);
1618 entityInfo->AnimationNodes = ExtractAnimations(scene, animationNames);
1619 entityInfo->UpAxis = GetUpAxis(scene->mRootNode);
1622 int numPointLights = 0;
1623 int numSpotLights = 0;
1624 int numDirectionalLights = 0;
1625 for (
int i = 0; i < entityInfo->Lights->Count; ++i)
1627 auto lightType = entityInfo->Lights[i]->Data->Type;
1630 else if (lightType == LightType::Directional)
1631 ++numDirectionalLights;
1632 else if (lightType == LightType::Spot)
1636 for (
int i = 0; i < entityInfo->Models->Count; ++i)
1638 entityInfo->Models[i]->Parameters->Add(LightingKeys::MaxPointLights, numPointLights);
1639 entityInfo->Models[i]->Parameters->Add(LightingKeys::MaxDirectionalLights, numDirectionalLights);
1640 entityInfo->Models[i]->Parameters->Add(LightingKeys::MaxSpotLights, numSpotLights);
1654 Assimp::Importer importer;
1655 auto scene = Initialize(inputFilename, outputFilename, &importer,
1656 aiProcess_CalcTangentSpace
1657 | aiProcess_RemoveRedundantMaterials
1658 | aiProcess_Triangulate
1659 | aiProcess_GenNormals
1660 | aiProcess_JoinIdenticalVertices
1661 | aiProcess_LimitBoneWeights
1662 | aiProcess_SortByPType
1663 | aiProcess_FlipWindingOrder
1664 | aiProcess_FlipUVs );
1665 return ConvertAssimpScene(scene);
1671 Assimp::Importer importer;
1672 auto scene = Initialize(inputFilename, outputFilename, &importer, 0);
1673 return ProcessAnimation(scene);
Key of an effect parameter.
Base implementation for IMaterialNode.
TimeSpan Duration
Gets or sets the duration of this clip.
SiliconStudio.Paradox.Games.Mathematics.Vector2 Vector2
property bool AllowUnsignedBlendIndices
List< MeshBoneDefinition > Bones
The layout of a vertex buffer with a set of VertexElement.
void SetParameter(ParameterKey parameterKey, object value)
Set the value of a compilation parameter. Creates a new entry if necessary.
A node that describe a binary operation between two IMaterialNode
Represents a two dimensional mathematical vector.
Matrix LinkToMeshMatrix
The matrix to transform from mesh space to local space of this bone.
Describes hiderarchical nodes in a flattened array.
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
Represents a color in the form of rgb.
void AddCurve(string propertyName, AnimationCurve curve)
Adds a named curve.
float B
The blue component of the color.
TransformTRS Transform
The local transform.
void AddColorNode(ParameterKey< ShaderMixinSource > key, string referenceName, IMaterialNode node)
Adds a tree in the model.
String aiStringToString(aiString str)
ModelNodeFlags Flags
The flags of this node.
Quaternion aiQuaternionToQuaternion(aiQuaterniont< float > quat)
Description of a material.
Describes skinning for a Mesh, through a collection of MeshBoneDefinition.
float R
The red component of the color.
Color aiColor4ToColor(aiColor4D color)
Represents a three dimensional mathematical vector.
int NodeIndex
The node index in ModelViewHierarchyUpdater.NodeTransformations.
AnimationCurveInterpolationType InterpolationType
Gets or sets the interpolation type.
Data type for SiliconStudio.Paradox.Effects.ParameterCollection.
Represents a color in the form of rgba.
An aggregation of AnimationCurve with their channel names.
Base implementation for ILogger.
ModelData Convert(String^inputFilename, String^outputFilename)
void Error(string message, Exception exception, CallerInfo callerInfo=null)
Logs the specified error message with an exception.
static void Add(ref Matrix left, ref Matrix right, out Matrix result)
Determines the sum of two matrices.
CompressedTimeSpan aiTimeToPdxTimeSpan(double time, double aiTickPerSecond)
Data type for SiliconStudio.Paradox.Graphics.IndexBufferBinding.
Represents a four dimensional mathematical vector.
SiliconStudio.Core.Mathematics.Color Color
Data type for SiliconStudio.Paradox.Graphics.VertexBufferBinding.
void AddNode(string referenceName, IMaterialNode node)
Inserts a new tree in the material
Data type for SiliconStudio.Paradox.EntityModel.Entity.
EntityInfo ExtractEntity(String^inputFilename, String^outputFilename)
Operation
Enumeration of the different operations in the new Assimp's material stack.
Represents a 32-bit color (4 bytes) in the form of RGBA (in byte order: R, G, B, A).
string Name
The name of this node.
Vector3 aiVector3ToVector3(aiVector3D vec)
Color3 aiColor3ToColor3(aiColor3D color)
Data type for SiliconStudio.Paradox.Effects.Mesh.
Data type for SiliconStudio.Paradox.Effects.MeshDraw.
TrackingDictionary< PropertyKey, EntityComponentData > Components
Untyped base class for animation curves.
aiMaterial * SourceMaterial
Data type for SiliconStudio.Paradox.Effects.Model.
LightType aiLightTypeToPdxLightType(aiLightSourceType aiLightType, String^lightName, Logger^logger)
Describes a single transformation node, usually in a Model node hierarchy.
AnimationClip ConvertAnimation(String^inputFilename, String^outputFilename)
float G
The green component of the color.
SiliconStudio.Core.Mathematics.Vector3 Vector3
int ParentIndex
The parent node index.
Describes a bone cluster inside a Mesh.
Content of a GPU buffer (vertex buffer, index buffer, etc...).
Matrix aiMatrixToMatrix(aiMatrix4x4 mat)
List< MaterialInstanciation^> Instances
void Verbose(string message, Exception exception, CallerInfo callerInfo=null)
Logs the specified verbose message with an exception.
void Warning(string message, Exception exception, CallerInfo callerInfo=null)
Logs the specified warning message with an exception.
MeshConverter(Core::Diagnostics::Logger^logger)
property Vector3 ViewDirectionForTransparentZSort
A description of a single element for the input-assembler stage. This structure is related to Direct3...
Data type for SiliconStudio.Paradox.Engine.LightComponent.
Data type for SiliconStudio.Paradox.Engine.CameraComponent.
System.Windows.Point Point
Color4 aiColor3ToColor4(aiColor3D color)