std::shared_ptr<ResHandle> ResCache::getHandle( Resource* r ) { std::shared_ptr<ResHandle> handle(find(r)); if( handle == NULL ) { handle = load(r); GEN_ASSERT(handle); } else { update(handle); } return handle; }//ResCache::getHandle
std::shared_ptr<ResHandle> ResCache::load( Resource* r ) { // Create a new resource and add it to the lru list and map std::shared_ptr<IResourceLoader> loader; std::shared_ptr<ResHandle> handle; for( ResourceLoaders::iterator it = m_resourceLoaders.begin(); it != m_resourceLoaders.end(); ++it ) { std::shared_ptr<IResourceLoader> testLoader = *it; if( WildcardMatch(testLoader->VGetPattern().c_str(), r->m_name.c_str()) ) { loader = testLoader; break; } } if( !loader ) { GEN_ASSERT(loader && "Default resource loader not found!"); return handle; // Resource not loaded! } // determine which resource file it's located in bool found = false; ResourceFiles::iterator fileItr = m_files.begin(); while( fileItr != m_files.end() ) { if( (*fileItr)->VGetRawResourceSize(*r) == -1 ) ++fileItr; else { found = true; break; } } if( !found ) { GEN_LOG("ResCache","file not found: " + r->m_name); return std::shared_ptr<ResHandle>(); } int rawSize = (*fileItr)->VGetRawResourceSize(*r); if( rawSize < 0 ) { GEN_ASSERT(rawSize > 0 && "Resource size returned -1 - Resource not found"); return std::shared_ptr<ResHandle>(); } int allocSize = rawSize + ((loader->VAddNullZero()) ? (1) : (0)); char* rawBuffer = loader->VUseRawFile() ? allocate(allocSize) : new char[allocSize]; memset(rawBuffer, 0, allocSize); if( rawBuffer == NULL || (*fileItr)->VGetRawResource(*r, rawBuffer) == 0 ) { // resource cache out of memory return std::shared_ptr<ResHandle>(); } char* buffer = NULL; unsigned int size = 0; if( loader->VUseRawFile() ) { buffer = rawBuffer; handle = std::shared_ptr<ResHandle>(new ResHandle(*r, buffer, rawSize, this)); } else { size = loader->VGetLoadedResourceSize(rawBuffer, rawSize); buffer = allocate(size); if( rawBuffer == NULL || buffer == NULL ) { // resource cache out of memory return std::shared_ptr<ResHandle>(); } handle = std::shared_ptr<ResHandle>(new ResHandle(*r, buffer, size, this)); bool success = loader->VLoadResource(rawBuffer, rawSize, handle); if( loader->VDiscardRawBufferAfterLoad() ) { delete[] rawBuffer; } if( !success ) { // resource cache out of memory return std::shared_ptr<ResHandle>(); } } if( handle ) { m_lru.push_front(handle); m_resources[r->m_name] = handle; } GEN_ASSERT(loader && "Default resource loader not found!"); return handle; // ResCache is out of memory! }//ResCache::load
// Construct a quaternion from a CMatrix4x4 - uses upper left 3x3 only CQuaternion::CQuaternion ( const CMatrix4x4& m ) { // Calculate matrix scaling TFloat32 scaleX = Sqrt( m.e00*m.e00 + m.e01*m.e01 + m.e02*m.e02 ); TFloat32 scaleY = Sqrt( m.e10*m.e10 + m.e11*m.e11 + m.e12*m.e12 ); TFloat32 scaleZ = Sqrt( m.e20*m.e20 + m.e21*m.e21 + m.e22*m.e22 ); // Calculate inverse scaling to extract rotational values only GEN_ASSERT( !gen::IsZero(scaleX) && !gen::IsZero(scaleY) && !gen::IsZero(scaleZ), "Cannot extract rotation from singular matrix" ); TFloat32 invScaleX = 1.0f / scaleX; TFloat32 invScaleY = 1.0f / scaleY; TFloat32 invScaleZ = 1.0f / scaleZ; // Calculate trace of matrix (the sum of diagonal elements) TFloat32 diagX = m.e00 * invScaleX; // Remove scaling TFloat32 diagY = m.e11 * invScaleY; TFloat32 diagZ = m.e22 * invScaleZ; TFloat32 trace = diagX + diagY + diagZ; // Simple method if trace is positive if (trace > 0.0f) { // Derive quaternion from remaining elements TFloat32 s = Sqrt( trace + 1.0f ); w = s * 0.5f; TFloat32 invS = 0.5f / s; x = (m.e12*invScaleY - m.e21*invScaleZ) * invS; y = (m.e20*invScaleZ - m.e02*invScaleX) * invS; z = (m.e01*invScaleX - m.e10*invScaleY) * invS; } else { // Find largest x,y or z axis component by manipulating diagonal elts TFloat32 maxAxis, invMaxAxis; if (diagX > diagY) { if (diagX > diagZ) { maxAxis = Sqrt( diagX - diagY - diagZ + 1.0f ); x = 0.5f * maxAxis; invMaxAxis = 0.5f / maxAxis; y = (m.e01*invScaleX + m.e10*invScaleY) * invMaxAxis; z = (m.e20*invScaleZ + m.e02*invScaleX) * invMaxAxis; w = (m.e12*invScaleY - m.e21*invScaleZ) * invMaxAxis; } else { maxAxis = Sqrt( diagZ - diagX - diagY + 1.0f ); z = 0.5f * maxAxis; invMaxAxis = 0.5f / maxAxis; x = (m.e20*invScaleZ + m.e02*invScaleX) * invMaxAxis; y = (m.e12*invScaleY + m.e21*invScaleZ) * invMaxAxis; w = (m.e01*invScaleX - m.e10*invScaleY) * invMaxAxis; } } else if (diagY > diagZ) { maxAxis = Sqrt( diagY - diagZ - diagX + 1.0f ); y = 0.5f * maxAxis; invMaxAxis = 0.5f / maxAxis; z = (m.e12*invScaleY + m.e21*invScaleZ) * invMaxAxis; x = (m.e01*invScaleX + m.e10*invScaleY) * invMaxAxis; w = (m.e20*invScaleZ - m.e02*invScaleX) * invMaxAxis; } else { maxAxis = Sqrt( diagZ - diagX - diagY + 1.0f ); z = 0.5f * maxAxis; invMaxAxis = 0.5f / maxAxis; x = (m.e20*invScaleZ + m.e02*invScaleX) * invMaxAxis; y = (m.e12*invScaleY + m.e21*invScaleZ) * invMaxAxis; w = (m.e01*invScaleX - m.e10*invScaleY) * invMaxAxis; } } }