예제 #1
0
NiNodeRef Exporter::createNode()
{
	NiNodeRef node = CreateNiObject<NiNode>();
	if (IsFallout3() || IsSkyrim()) {
		node->SetFlags(14);
	}
	return node;
}
예제 #2
0
NiNodeRef Exporter::getNode(const string& name)
{
   NodeMap::iterator itr = mNameMap.find(name);
   if (itr != mNameMap.end())
      return (*itr).second;
   NiNodeRef node = CreateNiObject<NiNode>();
   if ( IsFallout3() || IsSkyrim() ) {
      node->SetFlags( 14 );
   }
   node->SetName(name);
   mNameMap[name] = node;
   return node;
}
예제 #3
0
bool Exporter::makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, TimeValue t)
{
   if (!mExportSkin)
      return false;

   if (grp.verts.empty())
      return false;

   //get the skin modifier
   Modifier *mod = GetSkin(node);
   if (!mod)
      return false;

   ISkin *skin = (ISkin *) mod->GetInterface(I_SKIN);
   if (!skin)
      return false;

   ISkinContextData *skinData = skin->GetContextInterface(node);
   if (!skinData)
      return false;

   if (grp.strips.empty())
      strippify(grp);

   // Create new call back to finish export
   SkinInstance* si = new SkinInstance(this);
   mPostExportCallbacks.push_back(si);

   skin->GetSkinInitTM(node, si->bone_init_tm, false);
   skin->GetSkinInitTM(node, si->node_init_tm, true);

   si->shape = shape;

   // Get bone references (may not actually exist in proper structure at this time)
   int totalBones = skin->GetNumBones();
   si->boneWeights.resize(totalBones);
   si->boneList.resize(totalBones);
   for (int i=0; i<totalBones; ++i) {
      si->boneList[i] = getNode(skin->GetBone(i));
   }

   vector<int>& vidx = grp.vidx;
   int nv = vidx.size();
   for (int i=0; i<nv; ++i)
   {
      int vi = vidx[i];
      int nbones = skinData->GetNumAssignedBones(vi);
      for (int j=0; j<nbones; ++j)
      {
         SkinWeight sw;
         sw.index = i;
         sw.weight = skinData->GetBoneWeight(vi,j);
         int boneIndex = skinData->GetAssignedBone(vi,j);

         SkinInstance::SkinWeightList& weights = si->boneWeights[boneIndex];
         weights.push_back(sw);
      }         
   }

   // remove unused bones
   vector<NiNodeRef>::iterator bitr = si->boneList.begin();
   SkinInstance::BoneWeightList::iterator switr = si->boneWeights.begin();
   for (int i=0; i<totalBones; ++i) {
      vector<SkinWeight> &weights = (*switr);
      if (weights.empty())
      {
         bitr = si->boneList.erase(bitr);
         switr = si->boneWeights.erase(switr);
      }
      else
      {
         ++bitr, ++switr;
      }      
   }

   // Check for dismemberment
   if (IsFallout3() || IsSkyrim()) {
      Modifier *dismemberSkinMod = GetBSDismemberSkin(node);
      if (dismemberSkinMod)
      {
         if (IBSDismemberSkinModifier *disSkin = (IBSDismemberSkinModifier *) dismemberSkinMod->GetInterface(I_BSDISMEMBERSKINMODIFIER)){
            Tab<IBSDismemberSkinModifierData*> modData = disSkin->GetModifierData();
            if (modData.Count() >= 1) {
               IBSDismemberSkinModifierData* bsdsmd = modData[0];
               si->SkinInstConstructor = BSDismemberSkinInstance::Create;
               Tab<BSDSPartitionData> &flags = bsdsmd->GetPartitionFlags();
               GenericNamedSelSetList &fselSet = bsdsmd->GetFaceSelList();

               FaceMap fmap;
               NiTriBasedGeomDataRef data = DynamicCast<NiTriBasedGeomData>(shape->GetData());
               vector<Triangle> tris = data->GetTriangles();
               for (int i=0; i<tris.size(); ++i) {
                  Triangle tri = tris[i];
                  fmap[ rotate(tri) ] = i;
               }
               // Build up list of partitions and face to partition map
               si->partitions.resize(flags.Count());
               si->facePartList.resize( grp.faces.size(), -1 );
               for (int i=0; i<flags.Count(); ++i) {
                  BodyPartList& bp = si->partitions[i];
                  bp.bodyPart = (BSDismemberBodyPartType)flags[i].bodyPart;
                  bp.partFlag = (BSPartFlag)(flags[i].partFlag | PF_START_NET_BONESET);

                  BitArray& fSelect = fselSet[i];
                  for (int j=0; j<fSelect.GetSize(); ++j){
                     if ( fSelect[j] ) {
                        Triangle tri = grp.faces[grp.fidx[j]];
                        FaceMap::iterator fitr = fmap.find( rotate(tri) );
                        if (fitr != fmap.end())
                           si->facePartList[ (*fitr).second ] = i;
                     }
                  }
               }
            }
         }
      }
   }


   return true;
}
예제 #4
0
NiTriBasedGeomRef Exporter::makeMesh(NiNodeRef &parent, Mtl *mtl, FaceGroup &grp, bool exportStrips)
{
	NiTriBasedGeomRef shape;
	NiTriBasedGeomDataRef data;

   //if (Exporter::mFixNormals) {
   //   FixNormals(grp.faces, grp.verts, grp.vnorms);
   //}

	if (exportStrips) {
      shape = new NiTriStrips();
      data = new NiTriStripsData(grp.faces, !mUseAlternateStripper);
	} else {
      shape = new NiTriShape();
      data = new NiTriShapeData(grp.faces);
	}

   if ( IsFallout3() || IsSkyrim() )
      shape->SetFlags( 14 );

   data->SetVertices(grp.verts);
   data->SetNormals(grp.vnorms);
   data->SetVertexIndices(grp.vidx);
   data->SetUVSetMap(grp.uvMapping);

   int nUVs = grp.uvs.size();
   if ( IsFallout3() || IsSkyrim() )
      nUVs = min(1, nUVs);
   data->SetUVSetCount(nUVs);
   for (int i =0;i<nUVs; ++i) {
	   data->SetUVSet(i, grp.uvs[i]);
   }

   //if (IsSkyrim() && grp.vcolors.size() == 0)
   //   grp.vcolors.resize(grp.verts.size(), Color4(1.0f,1.0f,1.0f,1.0f));

	if (mVertexColors && grp.vcolors.size() > 0)
	{
		bool allWhite = true;
		Color4 white(1.0f, 1.0f, 1.0f, 1.0f);
		for (int i=0,n=grp.vcolors.size();i<n; ++i) {
			if (white != grp.vcolors[i]) {
				allWhite = false; 
				break;
			}
		}
		if (!allWhite)
			data->SetVertexColors(grp.vcolors);
	}

	data->SetConsistencyFlags(CT_STATIC);
	shape->SetData(data);

   if (Exporter::mTangentAndBinormalExtraData && (Exporter::mNifVersionInt > VER_4_2_2_0))
   {
      // enable traditional tangents and binormals for non-oblivion meshes
      if ( !IsOblivion() && (Exporter::mNifVersionInt >= VER_10_0_1_0) )
         data->SetTspaceFlag( 0x01 );
	   shape->UpdateTangentSpace(Exporter::mTangentAndBinormalMethod);
   }

	parent->AddChild(DynamicCast<NiAVObject>(shape));

   NiAVObjectRef av(DynamicCast<NiAVObject>(shape));
   makeMaterial(av, mtl);
   shape->SetActiveMaterial(0);

	return shape;
}