Skip to content
Snippets Groups Projects
Commit fb61ccae authored by Tazpn's avatar Tazpn
Browse files

Add options to force nubs to point back to parent node at the expense of the...

Add options to force nubs to point back to parent node at the expense of the rotation data.  It looks better. Need to alter the zAxis instead I think.
parent 36595961
No related branches found
No related tags found
No related merge requests found
......@@ -107,6 +107,11 @@ public:
bool hasSkeleton;
bool isBiped;
bool removeUnusedImportedBones;
bool forceRotation;
float minBoneWidth;
float maxBoneWidth;
float boneWidthToLengthRatio;
vector<NiObjectRef> blocks;
vector<NiNodeRef> nodes;
......@@ -169,6 +174,8 @@ public:
bool ImportSkin(ImpNode *node, NiTriBasedGeomRef triGeom);
Texmap* CreateTexture(TexDesc& desc);
INode *CreateBone(const string& name, Point3 startPos, Point3 endPos, Point3 zAxis);
};
......@@ -475,6 +482,11 @@ void NifImporter::LoadIniSettings()
bipedAnkleAttach = GetIniValue<float>(BipedImportSection, "BipedAnkleAttach", 0.2f);
bipedTrianglePelvis = GetIniValue<bool>(BipedImportSection, "BipedTrianglePelvis", false);
removeUnusedImportedBones = GetIniValue<bool>(BipedImportSection, "RemoveUnusedImportedBones", false);
forceRotation = GetIniValue<bool>(BipedImportSection, "ForceRotation", false);
minBoneWidth = GetIniValue<float>(BipedImportSection, "MinBoneWidth", 0.5f);
maxBoneWidth = GetIniValue<float>(BipedImportSection, "MaxBoneWidth", 3.0f);
boneWidthToLengthRatio = GetIniValue<float>(BipedImportSection, "BoneWidthToLengthRatio", 0.25f);
importSkeleton = hasSkeleton = HasSkeleton();
isBiped = IsBiped();
......@@ -738,7 +750,7 @@ void NifImporter::ScaleBiped(IBipMaster* master, NiNodeRef block, bool Recurse)
}
INode *CreateBone(const string& name, Point3 startPos, Point3 endPos, Point3 zAxis)
INode *NifImporter::CreateBone(const string& name, Point3 startPos, Point3 endPos, Point3 zAxis)
{
if (FPInterface * fpBones = GetCOREInterface(Interface_ID(0x438aff72, 0xef9675ac)))
{
......@@ -751,12 +763,8 @@ INode *CreateBone(const string& name, Point3 startPos, Point3 endPos, Point3 zAx
if (INode *n = result.n)
{
n->SetName(const_cast<TCHAR*>(name.c_str()));
const float wmin = 0.5f;
const float wmax = 3.0f;
float len = fabs(Length(startPos)-Length(endPos));
float width = max(wmin, min(wmax, len / 4.0f));
float width = max(minBoneWidth, min(maxBoneWidth, len * boneWidthToLengthRatio));
if (Object* o = n->GetObjectRef())
{
setMAXScriptValue(o->GetReference(0), "width", 0, width);
......@@ -784,6 +792,7 @@ void NifImporter::ImportBones(NiNodeRef node)
vector<NiNodeRef> children = DynamicCast<NiNode>(node->GetChildren());
NiNodeRef parent = node->GetParent();
PosRotScale prs = prsDefault;
Matrix3 im = TOMATRIX3(node->GetWorldTransform(), true);
Point3 p = im.GetTrans();
Quat q(im);
......@@ -795,13 +804,14 @@ void NifImporter::ImportBones(NiNodeRef node)
INode *pinode = bone->GetParentNode();
if (pinode)
bone->Detach(0,1);
PositionAndRotateNode(bone, p, q);
PositionAndRotateNode(bone, p, q, prs);
if (pinode)
pinode->AttachChild(bone, 1);
}
else
{
Vector3 ppos;
Point3 zAxis(0,1,0);
if (!children.empty()) {
for (vector<NiNodeRef>::iterator itr=children.begin(), end = children.end(); itr != end; ++itr) {
Matrix44 cwt = (*itr)->GetWorldTransform();
......@@ -816,12 +826,18 @@ void NifImporter::ImportBones(NiNodeRef node)
Matrix44 pwt = parent->GetWorldTransform();
Matrix33 prot; float pscale;
pwt.Decompose(ppos, prot, pscale);
if (forceRotation)
prs = prsPos;
}
else
{
if (forceRotation)
prs = prsPos;
}
Point3 pp(ppos.x, ppos.y, ppos.z);
Point3 zAxis(0,1,0);
if (bone = CreateBone(name, p, pp, zAxis))
{
PositionAndRotateNode(bone, p, q);
PositionAndRotateNode(bone, p, q, prs);
if (parent)
{
if (INode *pn = gi->GetINodeByName(parent->GetName().c_str()))
......
......@@ -44,6 +44,12 @@ BipedAnkleAttach=0.2
BipedTrianglePelvis=0
; Remove unused bones from the biped on import of a mesh. Default: 1
RemoveUnusedImportedBones=1
; Minimum Bone Width / Maximum Bone Width / Ratio of Width to Length
MinBoneWidth=0.5
MaxBoneWidth=3
BoneWidthToLengthRatio=0.25
; Force nub to point back to parent at expense of loss of rotation. Default: 1
ForceRotation=1
;; [Applications]
......
......@@ -356,7 +356,7 @@ Modifier *GetSkin(INode *node)
// Set Position and Rotation on a standard controller will need to handle bipeds
// Always in World Transform coordinates
void PositionAndRotateNode(INode *n, Point3 p, Quat& q, TimeValue t)
void PositionAndRotateNode(INode *n, Point3 p, Quat& q, PosRotScale prs, TimeValue t)
{
if (Control *c = n->GetTMController()) {
......@@ -368,15 +368,19 @@ void PositionAndRotateNode(INode *n, Point3 p, Quat& q, TimeValue t)
// Get the Biped Export Interface from the controller
//IBipedExport *BipIface = (IBipedExport *) c->GetInterface(I_BIPINTERFACE);
IOurBipExport *BipIface = (IOurBipExport *) c->GetInterface(I_OURINTERFACE);
BipIface->SetBipedRotation(q, t, n, 0/*???*/);
BipIface->SetBipedPosition(p, t, n);
if (prs & prsRot)
BipIface->SetBipedRotation(q, t, n, 0/*???*/);
if (prs & prsPos)
BipIface->SetBipedPosition(p, t, n);
}
else
{
if (Control *rotCtrl = c->GetRotationController())
rotCtrl->SetValue(t, &q, 1, CTRL_ABSOLUTE);
if (Control *posCtrl = c->GetPositionController())
posCtrl->SetValue(t, &p, 1, CTRL_ABSOLUTE);
if (prs & prsRot)
if (Control *rotCtrl = c->GetRotationController())
rotCtrl->SetValue(t, &q, 1, CTRL_ABSOLUTE);
if (prs & prsPos)
if (Control *posCtrl = c->GetPositionController())
posCtrl->SetValue(t, &p, 1, CTRL_ABSOLUTE);
}
}
}
......
......@@ -194,7 +194,15 @@ extern void FindImages(NameValueCollection& images, const string& rootPath, cons
extern void RenameNode(Interface *gi, LPCTSTR SrcName, LPCTSTR DstName);
extern TriObject* GetTriObject(Object *o);
extern Modifier *GetSkin(INode *node);
extern void PositionAndRotateNode(INode *n, Point3 p, Quat& q, TimeValue t = 0);
enum PosRotScale
{
prsPos = 0x1,
prsRot = 0x2,
prsScale = 0x4,
prsDefault = prsPos | prsRot | prsScale,
};
extern void PositionAndRotateNode(INode *n, Point3 p, Quat& q, PosRotScale prs = prsDefault, TimeValue t = 0);
extern Niflib::NiNodeRef FindNodeByName( const vector<Niflib::NiNodeRef>& blocks, const string& name );
extern std::vector<Niflib::NiNodeRef> SelectNodesByName( const vector<Niflib::NiNodeRef>& blocks, LPCTSTR match);
......@@ -218,4 +226,8 @@ static inline Matrix3 TOMATRIX3(const Niflib::Matrix44 &tm, bool invert = true){
return m;
}
static inline Quat TOQUAT(const Niflib::Quaternion& q){
return Quat(q.x, q.y, q.z, q.w);
}
#endif // _NIUTILS_H_
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment