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( ... ) { } }
void Frustum::Update(const Matrix44<float>& aCameraOrientation, float aAspectRatio, float aFov) { float Hnear = 2.f * tan(aFov / 2.f) * myNear; float Wnear = Hnear * aAspectRatio; myPosition = aCameraOrientation.GetTranslation(); Vector3f rightVector = GetNormalized(aCameraOrientation.GetRightVector()); Vector3f forwardVector = GetNormalized(aCameraOrientation.GetForwardVector()); Vector3f upVector = GetNormalized(aCameraOrientation.GetUpVector()); Vector3f nc = myPosition + forwardVector * myNear; Vector3f ntl = nc + (upVector * Hnear / 2.f) - (rightVector * Wnear / 2.f); Vector3f ntr = nc + (upVector * Hnear / 2.f) + (rightVector * Wnear / 2.f); Vector3f nbl = nc - (upVector * Hnear / 2.f) - (rightVector * Wnear / 2.f); Vector3f nbr = nc - (upVector * Hnear / 2.f) + (rightVector * Wnear / 2.f); float Hfar = 2.f * tan(aFov / 2.f) * myFar; float Wfar = Hfar * aAspectRatio; Vector3f fc = myPosition + forwardVector * myFar; Vector3f ftl = fc + (upVector * Hfar / 2.f) - (rightVector * Wfar / 2.f); Vector3f ftr = fc + (upVector * Hfar / 2.f) + (rightVector * Wfar / 2.f); Vector3f fbl = fc - (upVector * Hfar / 2.f) - (rightVector * Wfar / 2.f); Vector3f fbr = fc - (upVector * Hfar / 2.f) + (rightVector * Wfar / 2.f); myPointPositions[0] = ntl; myPointPositions[1] = ntr; myPointPositions[2] = nbl; myPointPositions[3] = nbr; myPointPositions[4] = ftl; myPointPositions[5] = ftr; myPointPositions[6] = fbl; myPointPositions[7] = fbr; Plane<float> plane; plane.InitWith3Points(myPosition, nbr, ntr); myPlanes[int(eFRUSTUMSIDES::eRIGHT)] = plane; plane.InitWith3Points(myPosition, ntl, nbl); myPlanes[int(eFRUSTUMSIDES::eLEFT)] = plane; plane.InitWith3Points(myPosition, ntr, ntl); myPlanes[int(eFRUSTUMSIDES::eUP)] = plane; plane.InitWith3Points(myPosition, nbl, nbr); myPlanes[int(eFRUSTUMSIDES::eDOWN)] = plane; plane.InitWithPointAndNormal(myPosition + (forwardVector * myFar), forwardVector); myPlanes[int(eFRUSTUMSIDES::eFAR)] = plane; plane.InitWithPointAndNormal(myPosition + (forwardVector * myNear), (forwardVector * -1.f)); myPlanes[int(eFRUSTUMSIDES::eNEAR)] = plane; myPosition += forwardVector * (myFar / 2.f); myLines.RemoveAll(); //Near Plane myLines.Add(CU::RenderCommandLine(ntl, ntr)); myLines.Add(CU::RenderCommandLine(ntr, nbr)); myLines.Add(CU::RenderCommandLine(nbr, nbl)); myLines.Add(CU::RenderCommandLine(nbl, ntl)); //Far plane myLines.Add(CU::RenderCommandLine(ftl, ftr)); myLines.Add(CU::RenderCommandLine(ftr, fbr)); myLines.Add(CU::RenderCommandLine(fbr, fbl)); myLines.Add(CU::RenderCommandLine(fbl, ftl)); //Sides myLines.Add(CU::RenderCommandLine(ntl, ftl)); myLines.Add(CU::RenderCommandLine(ntr, ftr)); myLines.Add(CU::RenderCommandLine(nbr, fbr)); myLines.Add(CU::RenderCommandLine(nbl, fbl)); }