Beispiel #1
0
void ObjectDetector::RegisterObject( ObjectDetectorLink& iLink, HOBJECT hObject, void* pUserData )
{
	// Make sure it isn't registered somewhere else first...
	ReleaseLink( iLink );

	// Make sure the object is valid
	if( !hObject )
	{
		return;
	}

	// Assign the new object and detector
	iLink.m_hObject = hObject;
	iLink.m_pDetector = this;
	iLink.m_pUserData = pUserData;
	++m_nRegisteredObjects;

	// Now hook it up to the root link...
	iLink.m_pPrev = &m_iRootLink;
	iLink.m_pNext = m_iRootLink.m_pNext;

	if( m_iRootLink.m_pNext )
	{
		m_iRootLink.m_pNext->m_pPrev = &iLink;
	}

	m_iRootLink.m_pNext = &iLink;
}
Beispiel #2
0
// Stop all links
void StopAllLink(HUB *h)
{
	LINK **link_list;
	UINT num_link;
	UINT i;
	// Validate arguments
	if (h == NULL)
	{
		return;
	}

	LockList(h->LinkList);
	{
		link_list = ToArray(h->LinkList);
		num_link = LIST_NUM(h->LinkList);
		for (i = 0;i < num_link;i++)
		{
			AddRef(link_list[i]->ref);
		}
	}
	UnlockList(h->LinkList);

	for (i = 0;i < num_link;i++)
	{
		StopLink(link_list[i]);
		ReleaseLink(link_list[i]);
	}

	Free(link_list);
}
Beispiel #3
0
// Release all links
void ReleaseAllLink(HUB *h)
{
	LINK **kk;
	UINT num, i;
	// Validate arguments
	if (h == NULL)
	{
		return;
	}

	LockList(h->LinkList);
	{
		num = LIST_NUM(h->LinkList);
		kk = ToArray(h->LinkList);
		DeleteAll(h->LinkList);
	}
	UnlockList(h->LinkList);

	for (i = 0;i < num;i++)
	{
		LINK *k = kk[i];

		ReleaseLink(k);
	}

	Free(kk);
}
Beispiel #4
0
ObjectDetector::~ObjectDetector()
{
	// Detach all the links
	while( m_iRootLink.m_pNext )
	{
		ReleaseLink( *m_iRootLink.m_pNext );
	}
}
Beispiel #5
0
// Delete the link
void DelLink(HUB *hub, LINK *k)
{
	// Validate arguments
	if (hub == NULL || k == NULL)
	{
		return;
	}

	LockList(hub->LinkList);
	{
		if (Delete(hub->LinkList, k))
		{
			ReleaseLink(k);
		}
	}
	UnlockList(hub->LinkList);
}
Beispiel #6
0
// リンクの削除
void DelLink(HUB *hub, LINK *k)
{
	// 引数チェック
	if (hub == NULL || k == NULL)
	{
		return;
	}

	LockList(hub->LinkList);
	{
		if (Delete(hub->LinkList, k))
		{
			ReleaseLink(k);
		}
	}
	UnlockList(hub->LinkList);
}
Beispiel #7
0
HOBJECT ObjectDetector::AcquireObject( bool bFromPrevious )
{
	// Make sure the object to the currently tracked link is still valid
	if( m_pTrackedLink && !m_pTrackedLink->m_hObject.GetData() )
	{
		ReleaseLink( *m_pTrackedLink );
		ClearObject();
	}

	// If we don't have any acquire flags set... then don't do anything
	if( !( m_nBehaviorFlags & ODBF_ACQUIREMASK ) )
	{
		return NULL;
	}

	// Keep track of the links that fit the previous, best, and current requirements
	ObjectDetectorLink* pPrevTracked = ( bFromPrevious ? m_pTrackedLink : NULL );
	ObjectDetectorLink* pCurrTracked = NULL;
	ObjectDetectorLink* pBestTracked = NULL;

	// Requirement ranges and other data tracking variables
	float fPrevRR = 0.0f;
	float fCurrRR = 1000000.0f;
	float fBestRR = 1000000.0f;
	float fTempRR, fActiveRR;
	uint32 nAttemptedTests, nPassedTests;
	bool bContinue;

	// Get the previously tracked link data... add up the RR values even if the
	// tests don't pass.  This way we get a relative value to compare to regardless
	// of whether it can be acquired again during this attempt.
	if( pPrevTracked )
	{
		LTVector vPos, vDims;
		GetObjectSpatialData( pPrevTracked, vPos, vDims );

		if( m_nBehaviorFlags & ODBF_ACQUIREFORWARD )
		{
			TestParamsForward( pPrevTracked, vPos, vDims, fTempRR );
			fPrevRR += fTempRR;
		}

		if( m_nBehaviorFlags & ODBF_ACQUIREDIRECTION )
		{
			TestParamsDirection( pPrevTracked, vPos, vDims, fTempRR );
			fPrevRR += fTempRR;
		}

		if( m_nBehaviorFlags & ODBF_ACQUIREFOV )
		{
			TestParamsFOV( pPrevTracked, vPos, vDims, fTempRR );
			fPrevRR += fTempRR;
		}

		if( m_nBehaviorFlags & ODBF_ACQUIRESPHERE )
		{
			TestParamsSphere( pPrevTracked, vPos, vDims, fTempRR );
			fPrevRR += fTempRR;
		}

		if( m_nBehaviorFlags & ODBF_ACQUIRECYLINDER )
		{
			TestParamsCylinder( pPrevTracked, vPos, vDims, fTempRR );
			fPrevRR += fTempRR;
		}

		if( m_nBehaviorFlags & ODBF_ACQUIRECUSTOM )
		{
			TestParamsCustom( pPrevTracked, fTempRR );
			fPrevRR += fTempRR;
		}
	}

	// Go through each registered object
	ObjectDetectorLink* pLink = m_iRootLink.m_pNext;

	while( pLink )
	{
		LTVector vPos, vDims;
		GetObjectSpatialData( pLink, vPos, vDims );

		// Ignore the previous tracked link
		if( pLink == pPrevTracked )
		{
			pLink = pLink->m_pNext;
			continue;
		}

		// If this link has invalid object data... release it
		if( !pLink->m_hObject.GetData() )
		{
			ObjectDetectorLink* pRemove = pLink;
			pLink = pLink->m_pNext;
			ReleaseLink( *pRemove );
			continue;
		}

		// Check our user flag verification
		if( m_nUserFlagVerification )
		{
			uint32 nUserFlags;
			g_pLTClient->Common()->GetObjectFlags( pLink->m_hObject, OFT_User, nUserFlags );

			if( ( nUserFlags & m_nUserFlagVerification ) != m_nUserFlagVerification )
			{
				continue;
			}
		}

		// Zero out our temporary requirement range
		fActiveRR = 0.0f;
		nAttemptedTests = 0;
		nPassedTests = 0;

		// Check all the necessary params
		if( m_nBehaviorFlags & ODBF_ACQUIREFORWARD )
		{
			++nAttemptedTests;

			if( TestParamsForward( pLink, vPos, vDims, fTempRR ) )
			{
				fActiveRR += fTempRR;
				++nPassedTests;
			}
		}

		if( m_nBehaviorFlags & ODBF_ACQUIREDIRECTION )
		{
			++nAttemptedTests;

			if( TestParamsDirection( pLink, vPos, vDims, fTempRR ) )
			{
				fActiveRR += fTempRR;
				++nPassedTests;
			}
		}

		if( m_nBehaviorFlags & ODBF_ACQUIREFOV )
		{
			++nAttemptedTests;

			if( TestParamsFOV( pLink, vPos, vDims, fTempRR ) )
			{
				fActiveRR += fTempRR;
				++nPassedTests;
			}
		}

		if( m_nBehaviorFlags & ODBF_ACQUIRESPHERE )
		{
			++nAttemptedTests;

			if( TestParamsSphere( pLink, vPos, vDims, fTempRR ) )
			{
				fActiveRR += fTempRR;
				++nPassedTests;
			}
		}

		if( m_nBehaviorFlags & ODBF_ACQUIRECYLINDER )
		{
			++nAttemptedTests;

			if( TestParamsCylinder( pLink, vPos, vDims, fTempRR ) )
			{
				fActiveRR += fTempRR;
				++nPassedTests;
			}
		}

		if( m_nBehaviorFlags & ODBF_ACQUIRECUSTOM )
		{
			++nAttemptedTests;

			if( TestParamsCustom( pLink, fTempRR ) )
			{
				fActiveRR += fTempRR;
				++nPassedTests;
			}
		}

		// Make sure we passed the required tests...
		if( m_nBehaviorFlags & ODBF_INCLUSIVEACQUIRE )
		{
			bContinue = ( nPassedTests == nAttemptedTests );
		}
		else
		{
			bContinue = ( nPassedTests > 0 );
		}

		if( bContinue )
		{
			// Make sure we have a line of site to this object
			if( m_nBehaviorFlags & ODBF_ACQUIRELINEOFSITE )
			{
				bContinue = TestLineOfSite( pLink );
			}

			// If we passed the line of site test...
			if( bContinue )
			{
				// If the active test is better than our best... track it!
				if( fActiveRR < fBestRR )
				{
					fBestRR = fActiveRR;
					pBestTracked = pLink;
				}

				// If the active test is after our previous, but better than the current... track it too!
				if( ( fActiveRR > fPrevRR ) && ( fActiveRR < fCurrRR ) )
				{
					fCurrRR = fActiveRR;
					pCurrTracked = pLink;
				}
			}
		}

		// Move on to the next object
		pLink = pLink->m_pNext;
	}

	// Reset our verification timers
	memcpy( m_fActiveVerifyFailureDelays, m_fVerifyFailureDelays, sizeof( float ) * ODBF_TESTSAVAILABLE );

	// Set our tracked link to the proper one
	if( pCurrTracked )
	{
		SetLink( pCurrTracked );
	}
	else if( pBestTracked )
	{
		SetLink( pBestTracked );
	}
	else if( !pPrevTracked )
	{
		ClearObject();
	}

	return GetObject();
}
Beispiel #8
0
void ObjectDetector::Update( float fFrameTime )
{
	// If we don't have a tracked link... there's nothing to update!
	if( !m_pTrackedLink )
	{
		return;
	}

	// Make sure the link is still valid
	if( !m_pTrackedLink->m_hObject.GetData() )
	{
		ReleaseLink( *m_pTrackedLink );
		ClearObject();
		return;
	}

	// If we don't have any verify flags set... then don't do anything
	if( !( m_nBehaviorFlags & ODBF_VERIFYMASK ) )
	{
		return;
	}

	// Requirement ranges and other data tracking variables
	float fTempRR;
	uint32 nAttemptedTests = 0;
	uint32 nPassedTests = 0;

	UpdateObjectSpatialData();

	// Handle each verification type
	if( m_nBehaviorFlags & ODBF_VERIFYLINEOFSITE )
	{
		++nAttemptedTests;

		if( TestLineOfSite( m_pTrackedLink ) )
		{
			m_fActiveVerifyFailureDelays[ 0 ] = m_fVerifyFailureDelays[ 0 ];
			++nPassedTests;
		}
		else
		{
			if( m_fActiveVerifyFailureDelays[ 0 ] > 0.0f )
			{
				m_fActiveVerifyFailureDelays[ 0 ] -= fFrameTime;
				++nPassedTests;
			}
		}
	}

	if( m_nBehaviorFlags & ODBF_VERIFYFORWARD )
	{
		++nAttemptedTests;

		if( TestParamsForward( m_pTrackedLink, m_vTrackedSpatialPosition, m_vTrackedSpatialDimensions, fTempRR ) )
		{
			m_fActiveVerifyFailureDelays[ 1 ] = m_fVerifyFailureDelays[ 1 ];
			++nPassedTests;
		}
		else
		{
			if( m_fActiveVerifyFailureDelays[ 1 ] > 0.0f )
			{
				m_fActiveVerifyFailureDelays[ 1 ] -= fFrameTime;
				++nPassedTests;
			}
		}
	}

	if( m_nBehaviorFlags & ODBF_VERIFYDIRECTION )
	{
		++nAttemptedTests;

		if( TestParamsDirection( m_pTrackedLink, m_vTrackedSpatialPosition, m_vTrackedSpatialDimensions, fTempRR ) )
		{
			m_fActiveVerifyFailureDelays[ 2 ] = m_fVerifyFailureDelays[ 2 ];
			++nPassedTests;
		}
		else
		{
			if( m_fActiveVerifyFailureDelays[ 2 ] > 0.0f )
			{
				m_fActiveVerifyFailureDelays[ 2 ] -= fFrameTime;
				++nPassedTests;
			}
		}
	}

	if( m_nBehaviorFlags & ODBF_VERIFYFOV )
	{
		++nAttemptedTests;

		if( TestParamsFOV( m_pTrackedLink, m_vTrackedSpatialPosition, m_vTrackedSpatialDimensions, fTempRR ) )
		{
			m_fActiveVerifyFailureDelays[ 3 ] = m_fVerifyFailureDelays[ 3 ];
			++nPassedTests;
		}
		else
		{
			if( m_fActiveVerifyFailureDelays[ 3 ] > 0.0f )
			{
				m_fActiveVerifyFailureDelays[ 3 ] -= fFrameTime;
				++nPassedTests;
			}
		}
	}

	if( m_nBehaviorFlags & ODBF_VERIFYSPHERE )
	{
		++nAttemptedTests;

		if( TestParamsSphere( m_pTrackedLink, m_vTrackedSpatialPosition, m_vTrackedSpatialDimensions, fTempRR ) )
		{
			m_fActiveVerifyFailureDelays[ 4 ] = m_fVerifyFailureDelays[ 4 ];
			++nPassedTests;
		}
		else
		{
			if( m_fActiveVerifyFailureDelays[ 4 ] > 0.0f )
			{
				m_fActiveVerifyFailureDelays[ 4 ] -= fFrameTime;
				++nPassedTests;
			}
		}
	}

	if( m_nBehaviorFlags & ODBF_VERIFYCYLINDER )
	{
		++nAttemptedTests;

		if( TestParamsCylinder( m_pTrackedLink, m_vTrackedSpatialPosition, m_vTrackedSpatialDimensions, fTempRR ) )
		{
			m_fActiveVerifyFailureDelays[ 5 ] = m_fVerifyFailureDelays[ 5 ];
			++nPassedTests;
		}
		else
		{
			if( m_fActiveVerifyFailureDelays[ 5 ] > 0.0f )
			{
				m_fActiveVerifyFailureDelays[ 5 ] -= fFrameTime;
				++nPassedTests;
			}
		}
	}

	if( m_nBehaviorFlags & ODBF_VERIFYCUSTOM )
	{
		++nAttemptedTests;

		if( TestParamsCustom( m_pTrackedLink, fTempRR ) )
		{
			m_fActiveVerifyFailureDelays[ 6 ] = m_fVerifyFailureDelays[ 6 ];
			++nPassedTests;
		}
		else
		{
			if( m_fActiveVerifyFailureDelays[ 6 ] > 0.0f )
			{
				m_fActiveVerifyFailureDelays[ 6 ] -= fFrameTime;
				++nPassedTests;
			}
		}
	}

	// Make sure we passed the required tests...
	if( ( nPassedTests == 0 ) || ( ( m_nBehaviorFlags & ODBF_INCLUSIVEVERIFY ) && ( nPassedTests != nAttemptedTests ) ) )
	{
		ClearObject();
	}

	// Otherwise, see if we're in a delay for clearing the object... and apply that instead
	if( m_fActiveClearDelay != OD_INVALID_CLEAR_DELAY )
	{
		m_fActiveClearDelay -= fFrameTime;

		if( m_fActiveClearDelay <= 0.0f )
		{
			ClearObject();
		}
	}
}