Example #1
0
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);
    }
}
Example #2
0
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);
}
Example #3
0
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]);
    }
}
Example #4
0
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();
}
Example #5
0
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);
    }
}
Example #6
0
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);
    }
}
Example #7
0
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;
}
Example #9
0
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*/;
}