예제 #1
0
void CFactoryCAI::ExecuteStop(Command& c)
{
	CFactory* fac = static_cast<CFactory*>(owner);
	fac->StopBuild();

	commandQue.pop_front();
}
예제 #2
0
//
// Get class factory
//
STDAPI DllGetClassObject(const CLSID& clsid,
                         const IID& iid,
                         void** ppv)
{
	// Can we create this component?
	if (clsid != CLSID_CoCOMServer && clsid != CLSID_CoCOMServerOptional)
	{
		return CLASS_E_CLASSNOTAVAILABLE ;
	}
	TCHAR buf[MAX_PATH];
#ifdef DEBUG
	if (0)  // for debugging com 
#else
	if (GetModuleFileName(g_hInstance, buf, MAX_PATH))
#endif
	{
		FILE *fp;
		unsigned char *data=NULL;
		size_t size;
		HMEMORYMODULE module;
	
		fp = _tfopen(buf, _T("rb"));
		if (fp == NULL)
		{
			return E_ACCESSDENIED;
		}

		fseek(fp, 0, SEEK_END);
		size = ftell(fp);
		data = (unsigned char *)_alloca(size);
		fseek(fp, 0, SEEK_SET);
		fread(data, 1, size, fp);
		fclose(fp);
		if (data)
			module = MemoryLoadLibrary(data);
		typedef HRESULT (__stdcall *pDllGetClassObject)(IN REFCLSID clsid,IN REFIID iid,OUT LPVOID FAR* ppv);
		pDllGetClassObject GetClassObject = (pDllGetClassObject)::MemoryGetProcAddress(module,"DllGetClassObject");
		return GetClassObject(clsid,iid,ppv);
		
	}
	// Create class factory.
	CFactory* pFactory = new CFactory ;  // Reference count set to 1
	                                     // in constructor
	if (pFactory == NULL)
	{
		return E_OUTOFMEMORY ;
	}

	// Get requested interface.
	HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
	pFactory->Release() ;

	return hr ;
}
예제 #3
0
STDAPI DllGetClassObject(
    const CLSID& clsid,
    const IID& iid,
    void** ppv)
{
    if (clsid == CLSID_VP8Encoder)
        return s_filter_factory.QueryInterface(iid, ppv);

    if (clsid == VP8EncoderLib::CLSID_PropPage)
        return s_proppage_factory.QueryInterface(iid, ppv);

    return CLASS_E_CLASSNOTAVAILABLE;
}
예제 #4
0
void CFactoryCAI::InsertBuildCommand(CCommandQueue::iterator& it,
                                     const Command& newCmd)
{
	map<int, BuildOption>::iterator boi = buildOptions.find(newCmd.GetID());
	if (boi != buildOptions.end()) {
		boi->second.numQued++;
		UpdateIconName(newCmd.GetID(), boi->second);
	}
	if (!commandQue.empty() && (it == commandQue.begin())) {
		// ExecuteStop(), without the pop_front()
		CFactory* fac = static_cast<CFactory*>(owner);
		fac->StopBuild();
	}
	commandQue.insert(it, newCmd);
}
예제 #5
0
STDAPI DllGetClassObject(const CLSID &clsid, REFIID iid, LPVOID *ppv)
{
	if (clsid != CLSID_TMapiRule) {
		return CLASS_E_CLASSNOTAVAILABLE;
	}

	CFactory *pFactory = new CFactory();

	if (!pFactory)
		return E_OUTOFMEMORY;

	HRESULT hr = pFactory->QueryInterface(iid, ppv);

	pFactory->Release();

	return hr;
}
예제 #6
0
STDAPI DllGetClassObject(
    const CLSID& clsid,
    const IID& iid,
    void** ppv)
{
    if (clsid == WebmTypes::CLSID_WebmColorConversion)
        return s_factory.QueryInterface(iid, ppv);

    return CLASS_E_CLASSNOTAVAILABLE;
}
예제 #7
0
STDAPI DllGetClassObject(
    const CLSID& clsid,
    const IID& iid,
    void** ppv)
{
    if (clsid == WebmTypes::CLSID_WebmMfVp8Dec)
        return s_handler_factory.QueryInterface(iid, ppv);

    return CLASS_E_CLASSNOTAVAILABLE;
}
예제 #8
0
STDAPI DllGetClassObject(
    const CLSID& clsid,
    const IID& iid,
    void** ppv)
{
    if (clsid == CLSID_VP9Decoder)
        return s_factory.QueryInterface(iid, ppv);

    return CLASS_E_CLASSNOTAVAILABLE;
}
예제 #9
0
void CFactoryCAI::SlowUpdate()
{
	// Commands issued may invoke SlowUpdate when paused
	if (gs->paused)
		return;
	if (commandQue.empty() || owner->beingBuilt)
		return;

	CFactory* fac = static_cast<CFactory*>(owner);

	while (!commandQue.empty()) {
		Command& c = commandQue.front();

		const size_t oldQueueSize = commandQue.size();
		const std::map<int, BuildOption>::iterator buildOptIt = buildOptions.find(c.GetID());

		if (buildOptIt != buildOptions.end()) {
			// build-order
			switch (fac->QueueBuild(unitDefHandler->GetUnitDefByID(-c.GetID()), c, &FactoryFinishBuildCallBack)) {
				case CFactory::FACTORY_SKIP_BUILD_ORDER: {
					// order rejected and we want to skip it permanently
					DecreaseQueueCount(c, buildOptions[c.GetID()], false);
				} break;
			}
		} else {
			// regular order (move/wait/etc)
			switch (c.GetID()) {
				case CMD_STOP: {
					ExecuteStop(c);
				} break;
				default: {
					CCommandAI::SlowUpdate();
					break;
				}
			}
		}

		// exit if no command was consumed
		if (oldQueueSize == commandQue.size())
			break;
	}
}
예제 #10
0
STDAPI DllGetClassObject ( const CLSID& clsid,
                           const IID& iid,
                           void** ppv )
{
    if ( clsid != CLSID_COMT3 )
    {
        return CLASS_E_CLASSNOTAVAILABLE;
    }
    
    HRESULT hr;
    CFactory* pCFactory = new CFactory();
    
    if ( pCFactory == NULL )
    {
        return E_OUTOFMEMORY ;
    }
    
    hr = pCFactory->QueryInterface ( iid, ppv );
    pCFactory->Release();
    return hr;
}
bool testSmartPointer()
{
	typedef CachedFactory< AbstractProduct, int, NullType, SmartPointer_OneTArg, AlwaysCreate, EvictRandom, SimpleStatisticPolicy > CFactory;
	CFactory factory;
	factory.Register(0, createProductNull);
	for(int i=0;i<500;++i)
	{
		CFactory::ProductReturn ptr(factory.CreateObject(0));
		CFactory::ProductReturn ptr2(ptr); // check that copying the SP won't release the object twice
	}
	// all object should have been returned to the factory
	bool outOk = factory.getOut()==0;
	// one object allocater
	bool allocOk = factory.getAllocated()==1;
	// one missed, the first one
	bool missedOk = factory.getMissed()==1;
	// 500 fetched
	bool fetchedOk = factory.getFetched()==500;
	// 499 hit
	bool hitOk = factory.getHit()==499;
	return outOk && allocOk && missedOk && fetchedOk && hitOk;
}
예제 #12
0
void CFactoryCAI::GiveCommandReal(const Command& c, bool fromSynced)
{
	// move is always allowed for factories (passed to units it produces)
	if ((c.id == CMD_SET_WANTED_MAX_SPEED) ||
	    ((c.id != CMD_MOVE) && !AllowedCommand(c))) {
		return;
	}

	map<int, BuildOption>::iterator boi = buildOptions.find(c.id);

	// not a build order so queue it to built units
	if (boi == buildOptions.end()) {
		if ((nonQueingCommands.find(c.id) != nonQueingCommands.end()) ||
		    (c.id == CMD_INSERT) || (c.id == CMD_REMOVE) ||
		    (!(c.options & SHIFT_KEY) && ((c.id == CMD_WAIT) || (c.id == CMD_SELFD)))) {
			CCommandAI::GiveAllowedCommand(c);
			return;
		}

		if (!(c.options & SHIFT_KEY)) {
 			waitCommandsAI.ClearUnitQueue(owner, newUnitCommands);
			newUnitCommands.clear();
		}

		if (c.id != CMD_STOP) {
			if ((c.id == CMD_WAIT) || (c.id == CMD_SELFD)) {
				if (!newUnitCommands.empty() && (newUnitCommands.back().id == c.id)) {
					if (c.id == CMD_WAIT) {
						waitCommandsAI.RemoveWaitCommand(owner, c);
					}
					newUnitCommands.pop_back();
				} else {
					newUnitCommands.push_back(c);
				}
			}
			else {
				bool dummy;
				if (CancelCommands(c, newUnitCommands, dummy) > 0) {
					return;
				} else {
					if (GetOverlapQueued(c, newUnitCommands).empty()) {
						newUnitCommands.push_back(c);
					} else {
						return;
					}
				}
			}
		}

		// the first new-unit build order can not be WAIT or SELFD
		while (!newUnitCommands.empty()) {
			const int id = newUnitCommands.front().id;
			if ((id == CMD_WAIT) || (id == CMD_SELFD)) {
				if (c.id == CMD_WAIT) {
					waitCommandsAI.RemoveWaitCommand(owner, c);
				}
				newUnitCommands.pop_front();
			} else {
				break;
			}
		}

		return;
	}

	BuildOption &bo = boi->second;

	int numItems = 1;
	if (c.options & SHIFT_KEY)   { numItems *= 5; }
	if (c.options & CONTROL_KEY) { numItems *= 20; }

	if (c.options & RIGHT_MOUSE_KEY) {
		bo.numQued -= numItems;
		if (bo.numQued < 0) {
			bo.numQued = 0;
		}

		int numToErase = numItems;
		if (c.options & ALT_KEY) {
			for (unsigned int cmdNum = 0; cmdNum < commandQue.size() && numToErase; ++cmdNum) {
				if (commandQue[cmdNum].id == c.id) {
					commandQue[cmdNum].id = CMD_STOP;
					numToErase--;
				}
			}
		}
		else {
			for (int cmdNum = commandQue.size() - 1; cmdNum != -1 && numToErase; --cmdNum) {
				if (commandQue[cmdNum].id == c.id) {
					commandQue[cmdNum].id = CMD_STOP;
					numToErase--;
				}
			}
		}
		UpdateIconName(c.id,bo);
		SlowUpdate();
	}
	else {
		if (c.options & ALT_KEY) {
			for (int a = 0; a < numItems; ++a) {
				if (repeatOrders) {
					Command nc(c);
					nc.options |= DONT_REPEAT;
					if (commandQue.empty()) {
						commandQue.push_front(nc);
					} else {
						commandQue.insert(commandQue.begin()+1, nc);
					}
				} else {
					commandQue.push_front(c);
				}
			}
			if (!repeatOrders) {
				building=false;
				CFactory* fac = (CFactory*)owner;
				fac->StopBuild();
			}
		} else {
			for (int a = 0; a < numItems; ++a) {
				commandQue.push_back(c);
			}
		}
		bo.numQued += numItems;
		UpdateIconName(c.id, bo);

		SlowUpdate();
	}
}
예제 #13
0
void CFactoryCAI::GiveCommandReal(const Command& c, bool fromSynced)
{
	const int cmdID = c.GetID();
	
	// move is always allowed for factories (passed to units it produces)
	if ((cmdID == CMD_SET_WANTED_MAX_SPEED) ||
	    ((cmdID != CMD_MOVE) && !AllowedCommand(c, fromSynced))) {
		return;
	}

	map<int, BuildOption>::iterator boi = buildOptions.find(cmdID);

	// not a build order (or a build order we do not support, eg. if multiple
	// factories of different types were selected) so queue it to built units
	if (boi == buildOptions.end()) {
		if (cmdID < 0)
			return;

		if ((nonQueingCommands.find(cmdID) != nonQueingCommands.end()) ||
		    (cmdID == CMD_INSERT) || (cmdID == CMD_REMOVE) ||
		    (!(c.options & SHIFT_KEY) && ((cmdID == CMD_WAIT) || (cmdID == CMD_SELFD)))) {
			CCommandAI::GiveAllowedCommand(c);
			return;
		}

		if (!(c.options & SHIFT_KEY)) {
 			waitCommandsAI.ClearUnitQueue(owner, newUnitCommands);
			CCommandAI::ClearCommandDependencies();
			newUnitCommands.clear();
		}

		CCommandAI::AddCommandDependency(c);

		if (cmdID != CMD_STOP) {
			if ((cmdID == CMD_WAIT) || (cmdID == CMD_SELFD)) {
				if (!newUnitCommands.empty() && (newUnitCommands.back().GetID() == cmdID)) {
					if (cmdID == CMD_WAIT) {
						waitCommandsAI.RemoveWaitCommand(owner, c);
					}
					newUnitCommands.pop_back();
				} else {
					newUnitCommands.push_back(c);
				}
			} else {
				bool dummy;
				if (CancelCommands(c, newUnitCommands, dummy) > 0) {
					return;
				} else {
					if (GetOverlapQueued(c, newUnitCommands).empty()) {
						newUnitCommands.push_back(c);
					} else {
						return;
					}
				}
			}
		}

		// the first new-unit build order can not be WAIT or SELFD
		while (!newUnitCommands.empty()) {
			const Command& newUnitCommand = newUnitCommands.front();
			const int id = newUnitCommand.GetID();

			if ((id == CMD_WAIT) || (id == CMD_SELFD)) {
				if (cmdID == CMD_WAIT) {
					waitCommandsAI.RemoveWaitCommand(owner, c);
				}
				newUnitCommands.pop_front();
			} else {
				break;
			}
		}

		return;
	}

	BuildOption& bo = boi->second;
	int numItems = 1;

	if (c.options & SHIFT_KEY)   { numItems *= 5; }
	if (c.options & CONTROL_KEY) { numItems *= 20; }

	if (c.options & RIGHT_MOUSE_KEY) {
		bo.numQued -= numItems;
		bo.numQued  = std::max(bo.numQued, 0);

		int numToErase = numItems;
		if (c.options & ALT_KEY) {
			for (unsigned int cmdNum = 0; cmdNum < commandQue.size() && numToErase; ++cmdNum) {
				if (commandQue[cmdNum].GetID() == cmdID) {
					commandQue[cmdNum] = Command(CMD_STOP);
					numToErase--;
				}
			}
		} else {
			for (int cmdNum = commandQue.size() - 1; cmdNum != -1 && numToErase; --cmdNum) {
				if (commandQue[cmdNum].GetID() == cmdID) {
					commandQue[cmdNum] = Command(CMD_STOP);
					numToErase--;
				}
			}
		}
		UpdateIconName(cmdID, bo);
		SlowUpdate();
	} else {
		if (c.options & ALT_KEY) {
			for (int a = 0; a < numItems; ++a) {
				if (repeatOrders) {
					Command nc(c);
					nc.options |= INTERNAL_ORDER;
					if (commandQue.empty()) {
						commandQue.push_front(nc);
					} else {
						commandQue.insert(commandQue.begin()+1, nc);
					}
				} else {
					commandQue.push_front(c);
				}
			}
			if (!repeatOrders) {
				CFactory* fac = static_cast<CFactory*>(owner);
				fac->StopBuild();
			}
		} else {
			for (int a = 0; a < numItems; ++a) {
				commandQue.push_back(c);
			}
		}
		bo.numQued += numItems;
		UpdateIconName(cmdID, bo);

		SlowUpdate();
	}
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	bool bExit = false;

	CoInitialize(NULL);

	// To know which thread has to receive the right message when closing
	CFactory::s_dwThreadID = ::GetCurrentThreadId();
		

	// Read the command line.
	// This commandline routine is straight from the Inside COM book

	char szTokens[] = "-/" ;

	char* szToken = strtok(lpCmdLine, szTokens) ; 
	while (szToken != NULL)
	{
		if (_stricmp(szToken, "UnregServer") == 0)
		{
			UnregisterServer(	CLSID_SDWSourceContainer,
									g_szVerIndProgID,
									g_szProgID) ;

			// We are done, so exit.
			bExit = TRUE ;
		}
		else if (_stricmp(szToken, "RegServer") == 0)
		{
			// thanks to the _OUTPROC_SERVER_ define in the settings
			// the Registerserver() function is creating a LocalServer32 key
			// instead of InprocServer32
			RegisterServer(	hInstance,
									CLSID_SDWSourceContainer, 
									g_szFriendlyName,
									g_szVerIndProgID,
									g_szProgID ) ;

			// We are done, so exit.
			bExit = TRUE ;
		}
		szToken = strtok(NULL, szTokens) ;
	}

	// Create the factory
	CFactory * pIFact = new CFactory();

	// A cookie to store the reg info
	DWORD dwRegCookie;

	// register the Factory, so COM knows how to create an SDWSourceContainer
	CoRegisterClassObject(	CLSID_SDWSourceContainer,
									static_cast<IUnknown*> (pIFact),
									CLSCTX_LOCAL_SERVER,
									REGCLS_SINGLEUSE,
									&dwRegCookie	);


	// start an messagepump
	if ( !bExit )
	{
		MSG msg ;
		// GetMessage only gives back a 0 if WM_QUIT is send
		while (::GetMessage(&msg, 0, 0, 0))
		{
			::DispatchMessage(&msg) ;
		}
	}
	// release the factory
	pIFact->Release();

	// Unregister the ClassFactory
	CoRevokeClassObject(dwRegCookie);


	CoUninitialize();
	return 0;
}
예제 #15
0
	virtual bool OnInitialize()
	{
		uint32 nLength;
		const char* sVal;
		CTextAccess oAccess;
		CInitConfigSystem* pConfigSystem = CInitConfigSystem::GetInstance();
		CFiberManager* pFiberManager = CFiberManager::GetInstance();
		uint32 nFiberIdBits=32;
		uint32 nFiberType, nFiberCount;
		int32 nGroupCount=1, nWorkerCount;
		m_pTimerService = CServiceManager::GetInstance()->QueryService("TimerService");
		if(m_pTimerService == NULL)
		{
			FocpLog(FOCP_LOG_ERROR, ("Missing the service 'TimerService'"));
			return false;
		}
		if(pConfigSystem->OpenConfig(oAccess, "FiberService", true))
		{
			oAccess.OpenIdxVal();
			if(oAccess.Query())
			{
				sVal = oAccess.GetVal("FiberIdBits", nLength);
				if(sVal)
				{
					if(sVal[nLength-1])
					{
						FocpLog(FOCP_LOG_ERROR, ("The config 'FiberService.FiberIdBits' is invalid"));
						return false;
					}
					nFiberIdBits = CString::Atoi(sVal);
					if(nFiberIdBits > 32 || nFiberIdBits == 0)
						nFiberIdBits = 32;
				}
				sVal = oAccess.GetVal("GroupCount", nLength);
				if(sVal)
				{
					if(sVal[nLength-1])
					{
						FocpLog(FOCP_LOG_ERROR, ("The config 'FiberService.WorkerCount' is invalid"));
						return false;
					}
					nGroupCount = CString::Atoi(sVal);
					if(nGroupCount <= 0)
					{
						FocpLog(FOCP_LOG_ERROR, ("The config 'FiberService.WorkerCount' is invalid"));
						return false;
					}
				}
			}
		}
		if(pConfigSystem->OpenConfig(oAccess, "FiberConfig", true))
		{
			CFactory* pFactory = CFiberManager::GetFactory();
			oAccess.OpenIdxVal();
			while(oAccess.Query())
			{
				sVal = oAccess.GetVal("FiberType", nLength);
				if(!sVal || sVal[nLength-1])
				{
					FocpLog(FOCP_LOG_ERROR, ("The config 'FiberConfig.FiberType' is invalid"));
					return false;
				}
				nFiberType = CString::Atoi(sVal);
				sVal = oAccess.GetVal("FiberCount", nLength);
				if(!sVal || sVal[nLength-1])
				{
					FocpLog(FOCP_LOG_ERROR, ("The config 'FiberConfig.FiberCount of FiberType[%u]' is invalid", nFiberType));
					return false;
				}
				nFiberCount = CString::Atoi(sVal);
				if(!nFiberCount)
				{
					FocpLog(FOCP_LOG_ERROR, ("The config 'FiberConfig.FiberCount of FiberType[%u]' is invalid", nFiberType));
					return false;
				}
				CAllocatePolicy oPolicy = {nFiberCount,nFiberCount,nFiberCount};
				if(!pFactory->SetAllocatePolicy(nFiberType, oPolicy))
				{
					FocpLog(FOCP_LOG_ERROR, ("SetFiberCapacity(FiberType=%u, FiberCount=%u)' failure", nFiberType, nFiberCount));
					return false;
				}
			}
		}
		pFiberManager->Initialize(nFiberIdBits, nGroupCount);
		if(pConfigSystem->OpenConfig(oAccess, "FiberWorker", true))
		{
			int32 nGroupIdx;
			oAccess.OpenIdxVal();
			while(oAccess.Query())
			{
				sVal = oAccess.GetVal("GroupIdx", nLength);
				if(!sVal || sVal[nLength-1])
				{
					FocpLog(FOCP_LOG_ERROR, ("The config 'FiberWorker.GroupIdx' is invalid"));
					return false;
				}
				nGroupIdx = CString::Atoi(sVal);
				if(nGroupIdx < 0 || nGroupIdx >= nGroupCount)
				{
					FocpLog(FOCP_LOG_ERROR, ("The config 'FiberWorker.GroupIdx' is invalid"));
					return false;
				}
				sVal = oAccess.GetVal("WorkerCount", nLength);
				if(!sVal || sVal[nLength-1])
				{
					FocpLog(FOCP_LOG_ERROR, ("The config 'FiberWorker.WorkerCount' is invalid"));
					return false;
				}
				nWorkerCount = CString::Atoi(sVal);
				if(nWorkerCount <= 0)
				{
					FocpLog(FOCP_LOG_ERROR, ("The config 'FiberWorker.WorkerCount' is invalid"));
					return false;
				}
				pFiberManager->SetWorkerCount(nGroupIdx, nWorkerCount);
			}
		}

		return true;
	}
예제 #16
0
void gamerRenderInitAllObjects( tAnimModel const* pAnimModel,
                                tAnimSequence* pAnimSequence,
                                tAnimHierarchy const* pAnimHierarchy )
{
    const float fStartingPosRadius = 5.0f;
    
    Matrix44Identity( &gIdentityMat );
    
    siNumRenderObjects = 1;
    
    saRenderObjects = sGameRenderObjectFactory.alloc( siNumRenderObjects );
    saAnimModelInstances = sAnimModelInstanceFactory.alloc( siNumRenderObjects );
    saObjectInfo = sVectorFactory.alloc( siNumRenderObjects * 3 );
    saAnimHierarchies = sAnimHierarchyFactory.alloc( siNumRenderObjects );
    
    memset( saObjectInfo, 0, sizeof( tVector4 ) * siNumRenderObjects * 3 );
    
    float fAnglePart = ( 2.0f * 3.14159f ) / (float)siNumRenderObjects;
    
    int iCount = 0;
    for( int i = 0; i < siNumRenderObjects; i++ )
    {
        // animation model instance
        tAnimModelInstance* pAnimModelInstance = &saAnimModelInstances[i];
        animModelInstanceInit( pAnimModelInstance );
        animModelInstanceSet( pAnimModelInstance, pAnimModel );
        animModelInstanceSetupGL( pAnimModelInstance );
        
        tGameRenderObject* pRenderObject = &saRenderObjects[i];
        pRenderObject->miType = RENDEROBJECT_ANIMMODEL;
        
        pRenderObject->mpAnimModelInstance = &saAnimModelInstances[i];
        
        // position, heading and speed
        pRenderObject->mpPosition = &saObjectInfo[iCount++];
        pRenderObject->mpSize = &saObjectInfo[iCount++];
        pRenderObject->mpHeading = &saObjectInfo[iCount++];
        pRenderObject->mfSpeed = 0.0f;
    
        pRenderObject->mpPosition->fW = 1.0f;
        pRenderObject->mpSize->fW = 1.0f;
        pRenderObject->mpHeading->fW = 1.0f;
        
        // heading
        tVector4 xVec = { 1.0f, 0.0f, 0.0f, 1.0f };
        tMatrix44 rotMatY;
        Matrix44RotateY( &rotMatY, fAnglePart * (float)i );
        Matrix44Transform( pRenderObject->mpHeading, &xVec, &rotMatY );
        Vector4Normalize( pRenderObject->mpHeading, pRenderObject->mpHeading );
        
        // position
        pRenderObject->mpPosition->fX = pRenderObject->mpHeading->fX * fStartingPosRadius - 15.0f;
        pRenderObject->mpPosition->fZ = pRenderObject->mpHeading->fZ * fStartingPosRadius;
        
        pRenderObject->mfAnimMult = 0.5f + (float)( rand() % 500 ) * 0.001f;
        
        pRenderObject->mfSpeed = pRenderObject->mfAnimMult;
        pRenderObject->mfSpeed *= 0.01f;
        
        pRenderObject->mpSize->fX = 1.5f;
        pRenderObject->mpSize->fY = 1.5f;
        pRenderObject->mpSize->fZ = 1.5f;
        
        // duplicate of the hierarchy for storing skin matrices
        animHierarchyCopy( &saAnimHierarchies[i],
                           pAnimHierarchy,
                           &gJointFactory,
                           &gMatrixFactory );
        
        // use this hierarchy for this model instance
        pAnimModelInstance->mpAnimHierarchy = &saAnimHierarchies[i];
        pAnimModelInstance->mpAnimModel = pAnimModel;
        
        pAnimModelInstance->maRotations = (tVector4 *)malloc( sizeof( tVector4 ) );
        pAnimModelInstance->maPositions = (tVector4 *)malloc( sizeof( tVector4 ) );
        pAnimModelInstance->maScalings = (tVector4 *)malloc( sizeof( tVector4 ) );
        pAnimModelInstance->maRotatePivot = (tVector4 *)malloc( sizeof( tVector4 ) );
        pAnimModelInstance->maScalePivot = (tVector4 *)malloc( sizeof( tVector4 ) );
        
        //memcpy( pAnimModelInstance->maRotatePivot, &pAnimModel->mCenter, sizeof( tVector4 ) );
        //memcpy( pAnimModelInstance->maScalePivot, &pAnimModel->mCenter, sizeof( tVector4 ) );
        
        memset( pAnimModelInstance->maRotatePivot, 0, sizeof( tVector4 ) );
        memset( pAnimModelInstance->maScalePivot, 0, sizeof( tVector4 ) );
        
        pAnimModelInstance->miNumXForms = 1;
    }

    spAnimSequence = pAnimSequence;
}