Пример #1
0
static bool HasUserPropBuffer(NiNodeRef node)
{
   if (node) {
      if (NiStringExtraDataRef data = SelectFirstObjectOfType<NiStringExtraData>(node->GetExtraData())){
         if (strmatch(data->GetName(), "UserPropBuffer"))
            return true;
      }
   }
   return false;
}
Пример #2
0
/*---------------------------------------------------------------------------*/
NiNodeRef NifPrepareUtility::parse4Blender(NiNodeRef pNode)
{
	vector<NiAVObjectRef>	childList(pNode->GetChildren());
	list<NiExtraDataRef>	extraList(pNode->GetExtraData());

	//  parse extra data for BSInvMarker
	for (auto pIter(extraList.begin()), pEnd(extraList.end()); pIter != pEnd; pIter++)
	{
		if (_remBSInvMarker && (DynamicCast<BSInvMarker>(*pIter) != NULL))
		{
			pNode->RemoveExtraData(*pIter);
		}
	}

	//  unlink children
	pNode->ClearChildren();

	//  iterate over children
	for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++)
	{
		//  NiTriShape => remove BSLightingShaderProperty
		if (DynamicCast<NiTriShape>(*pIter) != NULL)
		{
			if (_remBSProperties)
			{
				NiTriShapeRef	pShape (DynamicCast<NiTriShape>(*pIter));

				//  remove properties (Bethesda uses max. 2)
				pShape->SetBSProperty(0, NULL);
				pShape->SetBSProperty(1, NULL);
			}

			//  add shape to node
			pNode->AddChild(*pIter);
		}
		//  BSInvMarker => remove whole object
		else if (_remBSInvMarker && (DynamicCast<BSInvMarker>(*pIter) != NULL))
		{
			//  skip entry => do not add to final list
		}
		//  NiNode (and derived classes?) => iterate subnodes
		else if (DynamicCast<NiNode>(*pIter) != NULL)
		{
			pNode->AddChild(&(*parse4Blender(DynamicCast<NiNode>(*pIter))));
		}
	}  //  for (auto pIter(childList.begin()), pEnd(childList.end()); pIter != pEnd; pIter++)

	return pNode;
}
Пример #3
0
bool NifImporter::IsBiped()
{
   if (HasSkeleton()){
      NiNodeRef rootNode = root;
      if (rootNode){
         list<NiExtraDataRef> extraData = rootNode->GetExtraData();
         if (!extraData.empty()) {
			 if ( BSXFlagsRef flags = SelectFirstObjectOfType<BSXFlags>(extraData) ) {
				 return (flags->GetData() & 0x4);
			 }
         }
      }
   }
   return false;
}
Пример #4
0
void NifImporter::ImportBones(NiNodeRef node, bool recurse)
{
   try 
   {
      if (uncontrolledDummies)
         BuildControllerRefList(node, ctrlCount);

      string name = node->GetName();

      vector<NiAVObjectRef> children = node->GetChildren();
      vector<NiNodeRef> childNodes = DynamicCast<NiNode>(children);

      NiAVObject::CollisionType cType = node->GetCollisionMode();
      if (children.empty() && name == "Bounding Box")
         return;

      // Do all node manipulations here
      NiNodeRef parent = node->GetParent();
      string parentname = (parent ? parent->GetName() : "");
      Matrix44 m4 = node->GetWorldTransform();

      // Check for Prn strings and change parent if necessary
      if (supportPrnStrings) {
         list<NiStringExtraDataRef> strings = DynamicCast<NiStringExtraData>(node->GetExtraData());
         for (list<NiStringExtraDataRef>::iterator itr = strings.begin(); itr != strings.end(); ++itr){
            if (strmatch((*itr)->GetName(), "Prn")) {
               parentname = (*itr)->GetData();
               if (INode *pn = gi->GetINodeByName(parentname.c_str())){
                  // Apparently Heads tend to need to be rotated 90 degrees on import for 
                  if (!rotate90Degrees.empty() && wildmatch(rotate90Degrees, parentname)) {
                     m4 *= TOMATRIX4(RotateYMatrix(TORAD(90)));
                  }
                  m4 *= TOMATRIX4(pn->GetObjTMAfterWSM(0, NULL));
               }
            }
         }
      }

      float len = node->GetLocalTranslation().Magnitude();

      // Remove NonAccum nodes and merge into primary bone
      if (mergeNonAccum && wildmatch("* NonAccum", name) && parent)
      {
         string realname = name.substr(0, name.length() - 9);
         if (strmatch(realname, parent->GetName()))
         {
            Matrix44 tm = parent->GetLocalTransform() * node->GetLocalTransform();
            name = realname;
            len += tm.GetTranslation().Magnitude();
			parent = parent->GetParent();
         }
      }

      PosRotScale prs = prsDefault;
      Vector3 pos; Matrix33 rot; float scale;
      m4.Decompose(pos, rot, scale);

      Matrix3 im = TOMATRIX3(m4);
      Point3 p = im.GetTrans();
      Quat q(im);
      //q.Normalize();
      Vector3 ppos;
      Point3 zAxis(0,0,0);
      bool hasChildren = !children.empty();
      if (hasChildren) {
         float len = 0.0f;
         for (vector<NiAVObjectRef>::iterator itr=children.begin(), end = children.end(); itr != end; ++itr) {
            len += GetObjectLength(*itr);
         }
         len /= float(children.size());
         ppos = pos + Vector3(len, 0.0f, 0.0f); // just really need magnitude as rotation will take care of positioning
      }
      else if (parent)
      {
         ppos = pos + Vector3(len/3.0f, 0.0f, 0.0f);
      }
      Point3 pp(ppos.x, ppos.y, ppos.z);

      Point3 qp = TORAD(TOEULER(im));


      INode *bone = NULL;
	  if (!doNotReuseExistingBones) // Games like BC3 reuse the same bone names
	  {
		  bone = FindNode(node);
		  if (bone == NULL) 
			  bone = gi->GetINodeByName(name.c_str());
	  }
      if (bone)
      {
         // Is there a better way of "Affect Pivot Only" behaviors?
         INode *pinode = bone->GetParentNode();
         if (pinode)
            bone->Detach(0,1);
         PosRotScaleNode(bone, p, q, scale, prs);
         if (pinode)
            pinode->AttachChild(bone, 1);
      }
      else
      {
         bool isDummy = ( (uncontrolledDummies && !HasControllerRef(ctrlCount, name))
                     || (!dummyNodeMatches.empty() && wildmatch(dummyNodeMatches, name))
                     || (convertBillboardsToDummyNodes && node->IsDerivedType(NiBillboardNode::TYPE))
                      );
         if (wildmatch("Camera*", name)) {
            if (enableCameras) {
               if (bone = CreateCamera(name)) {
                  PosRotScaleNode(bone, p, q, scale, prs);
                  bone->Hide(node->GetVisibility() ? FALSE : TRUE);
               }
            }
         }else if (isDummy && createNubsForBones)
            bone = CreateHelper(name, p);
         else if (bone = CreateBone(name, p, pp, zAxis))
         {
            PosRotScaleNode(bone, p, q, scale, prs);
            bone->Hide(node->GetVisibility() ? FALSE : TRUE);
         }
         if (bone)
         {
            if (!parentname.empty())
            {
               if (mergeNonAccum && wildmatch("* NonAccum", parentname)) {
                  parentname = parentname.substr(0, parentname.length() - 9);
               }
               if (INode *pn = gi->GetINodeByName(parentname.c_str()))
                  pn->AttachChild(bone, 1);
            }
			RegisterNode(node, bone);
         }
      }
      // Import UPB
      if (bone) ImportUPB(bone, node);

      // Import Havok Collision Data surrounding node,  
	  //   unfortunately this causes double import of collision so I'm disabling it for now.
	  if (enableCollision && node->GetParent()) {
		ImportCollision(node);
	  }

      if (bone && recurse)
      {
         ImportBones(childNodes);
      }
   }
   catch( exception & e ) 
   {
      e=e;
   }
   catch( ... ) 
   {
   }
}