void Octree::CollectNodes(Vector<Pair<OctreeNode*, float> >& result, const Octant* octant, const Ray& ray, unsigned short nodeFlags, float maxDistance, unsigned layerMask) const { float octantDist = ray.HitDistance(octant->cullingBox); if (octantDist >= maxDistance) return; const Vector<OctreeNode*>& octantNodes = octant->nodes; for (auto it = octantNodes.Begin(); it != octantNodes.End(); ++it) { OctreeNode* node = *it; if ((node->Flags() & nodeFlags) == nodeFlags && (node->LayerMask() & layerMask)) { float distance = ray.HitDistance(node->WorldBoundingBox()); if (distance < maxDistance) result.Push(MakePair(node, distance)); } } for (size_t i = 0; i < NUM_OCTANTS; ++i) { if (octant->children[i]) CollectNodes(result, octant->children[i], ray, nodeFlags, maxDistance, layerMask); } }
void Octree::Raycast(Vector<RaycastResult>& result, const Ray& ray, unsigned short nodeFlags, float maxDistance, unsigned layerMask) { PROFILE(OctreeRaycast); result.Clear(); CollectNodes(result, &root, ray, nodeFlags, maxDistance, layerMask); Sort(result.Begin(), result.End(), CompareRaycastResults); }
void Octree::CollectNodes(Vector<OctreeNode*>& result, const Octant* octant) const { result.Push(octant->nodes); for (size_t i = 0; i < NUM_OCTANTS; ++i) { if (octant->children[i]) CollectNodes(result, octant->children[i]); } }
void Octree::Resize(const BoundingBox& boundingBox, int numLevels) { PROFILE(ResizeOctree); // Collect nodes to the root and delete all child octants updateQueue.Clear(); CollectNodes(updateQueue, &root); DeleteChildOctants(&root, false); allocator.Reset(); root.Initialize(nullptr, boundingBox, Clamp(numLevels, 1, MAX_OCTREE_LEVELS)); // Reinsert all nodes (recreates new child octants as necessary) Update(); }
void Octree::CollectNodes(Vector<OctreeNode*>& result, const Octant* octant, unsigned short nodeFlags, unsigned layerMask) const { const Vector<OctreeNode*>& octantNodes = octant->nodes; for (auto it = octantNodes.Begin(); it != octantNodes.End(); ++it) { OctreeNode* node = *it; if ((node->Flags() & nodeFlags) == nodeFlags && (node->LayerMask() & layerMask)) result.Push(node); } for (size_t i = 0; i < NUM_OCTANTS; ++i) { if (octant->children[i]) CollectNodes(result, octant->children[i], nodeFlags, layerMask); } }
void Octree::CollectNodes(Vector<RaycastResult>& result, const Octant* octant, const Ray& ray, unsigned short nodeFlags, float maxDistance, unsigned layerMask) const { float octantDist = ray.HitDistance(octant->cullingBox); if (octantDist >= maxDistance) return; const Vector<OctreeNode*>& octantNodes = octant->nodes; for (auto it = octantNodes.Begin(); it != octantNodes.End(); ++it) { OctreeNode* node = *it; if ((node->Flags() & nodeFlags) == nodeFlags && (node->LayerMask() & layerMask)) node->OnRaycast(result, ray, maxDistance); } for (size_t i = 0; i < NUM_OCTANTS; ++i) { if (octant->children[i]) CollectNodes(result, octant->children[i], ray, nodeFlags, maxDistance, layerMask); } }
RaycastResult Octree::RaycastSingle(const Ray& ray, unsigned short nodeFlags, float maxDistance, unsigned layerMask) { PROFILE(OctreeRaycastSingle); // Get first the potential hits initialRes.Clear(); CollectNodes(initialRes, &root, ray, nodeFlags, maxDistance, layerMask); Sort(initialRes.Begin(), initialRes.End(), CompareNodeDistances); // Then perform actual per-node ray tests and early-out when possible finalRes.Clear(); float closestHit = M_INFINITY; for (auto it = initialRes.Begin(); it != initialRes.End(); ++it) { if (it->second < Min(closestHit, maxDistance)) { size_t oldSize = finalRes.Size(); it->first->OnRaycast(finalRes, ray, maxDistance); if (finalRes.Size() > oldSize) closestHit = Min(closestHit, finalRes.Back().distance); } else break; } if (finalRes.Size()) { Sort(finalRes.Begin(), finalRes.End(), CompareRaycastResults); return finalRes.Front(); } else { RaycastResult emptyRes; emptyRes.position = emptyRes.normal = Vector3::ZERO; emptyRes.distance = M_INFINITY; emptyRes.node = nullptr; emptyRes.subObject = 0; return emptyRes; } }
void VWeightExportClass::CollectNodes( INode *pnode ) { // Get pre-stored "index" int index = ::GetIndexOfINode(pnode); if (index >= 0) { // Get name, store name in array TSTR strNodeName(pnode->GetName()); strcpy(m_MaxNode[index].szNodeName, (char*)strNodeName); // Get Node's time-zero Transformation Matrices m_MaxNode[index].mat3NodeTM = pnode->GetNodeTM(0); m_MaxNode[index].mat3ObjectTM = pnode->GetObjectTM(0); } for (int c = 0; c < pnode->NumberOfChildren(); c++) { CollectNodes(pnode->GetChildNode(c)); } return; }
int SmdExportClass::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts) { ExpInterface *pexpiface = ei; // Hungarian Interface *piface = i; // Hungarian // Reset the name-map property manager g_inmMac = 0; // Present the user with the Export Options dialog if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EXPORTOPTIONS), GetActiveWindow(), ExportOptionsDlgProc, (LPARAM)this) <= 0) return 0; // error or cancel // Break up filename, re-assemble longer versions TSTR strPath, strFile, strExt; TCHAR szFile[MAX_PATH]; SplitFilename(TSTR(name), &strPath, &strFile, &strExt); sprintf(szFile, "%s\\%s.%s", (char*)strPath, (char*)strFile, DEFAULT_EXT); /* if (m_fReferenceFrame) sprintf(szFile, "%s\\%s_model.%s", (char*)strPath, (char*)strFile, DEFAULT_EXT); */ FILE *pFile; if ((pFile = fopen(szFile, "w")) == NULL) return FALSE/*failure*/; fprintf( pFile, "version %d\n", 1 ); // Get animation metrics m_intervalOfAnimation = piface->GetAnimRange(); m_tvStart = m_intervalOfAnimation.Start(); m_tvEnd = m_intervalOfAnimation.End(); m_tpf = ::GetTicksPerFrame(); // Count nodes, label them, collect into array if (!CollectNodes(pexpiface)) return 0; /*fail*/ // Output nodes if (!DumpBones(pFile, pexpiface)) { fclose( pFile ); return 0; /*fail*/ } // Output bone rotations, for each frame. Do only first frame if this is the reference frame MAX file DumpRotations(pFile, pexpiface); // Output triangle meshes (first frame/all frames), if this is the reference frame MAX file if (m_fReferenceFrame) { DumpModel(pFile, pexpiface); } // Tell user that exporting is finished (it can take a while with no feedback) char szExportComplete[300]; sprintf(szExportComplete, "Exported %s.", szFile); MessageBox(GetActiveWindow(), szExportComplete, "Status", MB_OK); fclose( pFile ); return 1/*success*/; }
int VWeightExportClass::DoExport(const TCHAR *name, ExpInterface *ei, Interface *pi, BOOL suppressPrompts, DWORD options) { ExpInterface *pexpiface = ei; // Hungarian Interface *piface = pi; // Hungarian // Reset the name-map property manager ResetINodeMap(); // Break up filename, re-assemble longer versions TSTR strPath, strFile, strExt; TCHAR szFile[MAX_PATH]; SplitFilename(TSTR(name), &strPath, &strFile, &strExt); sprintf(szFile, "%s\\%s.%s", (char*)strPath, (char*)strFile, DEFAULT_EXT); // Get animation metrics m_intervalOfAnimation = piface->GetAnimRange(); m_tvStart = m_intervalOfAnimation.Start(); m_tvEnd = m_intervalOfAnimation.End(); m_tpf = ::GetTicksPerFrame(); Interface *ip = GetCOREInterface(); ResetINodeMap( ); m_cMaxNode = BuildINodeMap( ip->GetRootNode() ); // Count nodes, label them, collect into array CollectNodes( ip->GetRootNode() ); CollectModel( pexpiface ); #if 1 FILE *pFile; if ((pFile = fopen(szFile, "wb")) == NULL) return FALSE/*failure*/; int version = 1; fwrite( &version, 1, sizeof( int ), pFile ); int i, j; fwrite( &m_cMaxNode, 1, sizeof( int ), pFile ); fwrite( &m_cMaxVertex, 1, sizeof( int ), pFile ); for (i = 0; i < m_cMaxNode; i++) { fwrite( &m_MaxNode[i], 1, sizeof(m_MaxNode[i]), pFile ); } for (j = 0; j < m_cMaxVertex; j++) { fwrite( m_MaxVertex[j], m_cMaxNode, sizeof(MaxVertWeight), pFile ); } fclose( pFile ); #else FILE *pFile; if ((pFile = fopen(szFile, "w")) == NULL) return FALSE/*failure*/; fprintf( pFile, "version %d\n", 1 ); int i, j; fprintf(pFile, "%d\n", m_cMaxNode ); fprintf(pFile, "%d\n", m_cMaxVertex ); for (i = 0; i < m_cMaxNode; i++) { fprintf(pFile, "%5d \"%s\" %3d\n", i, m_MaxNode[i].szNodeName, m_MaxNode[i].imaxnodeParent ); } for (j = 0; j < m_cMaxVertex; j++) { fprintf( pFile, "%d ", j ); for (int i = 0; i < m_cMaxNode; i++) { // if (strstr(m_MaxNode[i].szNodeName, "Bip01 R Finger")) // if (m_MaxNode[i].szNodeName[0] == 'D') { fprintf(pFile, " %5.3f", m_MaxVertex[j][i].flDist ); fprintf(pFile, " %3.0f", m_MaxVertex[j][i].flWeight ); } } fprintf(pFile, "\n" ); } fclose( pFile ); #endif // Tell user that exporting is finished (it can take a while with no feedback) char szExportComplete[300]; sprintf(szExportComplete, "Exported %s.", szFile); MessageBox(GetActiveWindow(), szExportComplete, "Status", MB_OK); return 1/*success*/; }