void LSLuaState::finalizeAssemblyLoad(Assembly *assembly, utArray<Type *>& types) { for (UTsize j = 0; j < types.size(); j++) { Type *type = types.at(j); if (type->isNative() || type->hasStaticNativeMember()) { // we're native NativeInterface::resolveScriptType(type); } } declareLuaTypes(types); initializeLuaTypes(types); // we avoid runtime validation on mobile, this works but should be unnecessary // as issues with be caught on OSX/WINDOWS development platforms #if LOOM_PLATFORM == LOOM_PLATFORM_OSX || LOOM_PLATFORM == LOOM_PLATFORM_WIN32 for (UTsize j = 0; j < types.size(); j++) { Type *type = types.at(j); TypeValidatorRT tv(this, type); tv.validate(); } #endif assembly->bootstrap(); }
void gkBlenderSceneConverter::applyParents(utArray<Blender::Object*> &children) { UTsize i; for (i = 0; i < children.size(); i++) { Blender::Object* bchild = children.at(i); gkGameObject* gchild = m_gscene->getObject(GKB_IDNAME(bchild)); if (gchild) { gkGameObject* gpar = m_gscene->getObject(GKB_IDNAME(bchild->parent)); if (gpar && !gpar->getProperties().hasBoneParent()) gchild->setParent(gpar); } } }
void LSLuaState::declareLuaTypes(const utArray<Type *>& types) { for (UTsize i = 0; i < types.size(); i++) { declareClass(types[i]); } // validate/initialize native types for (UTsize i = 0; i < types.size(); i++) { Type *type = types.at(i); if (type->isNative() || type->hasStaticNativeMember()) { NativeTypeBase *ntb = NativeInterface::getNativeType(type); if (!ntb) { LSError("Unable to get NativeTypeBase for type %s", type->getFullName().c_str()); } if (type->isNativeManaged() != ntb->isManaged()) { if (type->isNativeManaged()) { LSError("Managed mismatch for type %s, script declaration specifies native while native bindings are unmanaged", type->getFullName().c_str()); } else { LSError("Managed mismatch for type %s, script declaration specifies unmanaged while native bindings are managed", type->getFullName().c_str()); } } ntb->validate(type); type->setCTypeName(ntb->getCTypeName()); } } }
// Take a difference report from compareFileEntries and issue appropriate // file modification notes, and check whether they have settled. If so, // transmit updates to clients. static void processFileEntryDeltas(utArray<FileEntryDelta> *deltas) { int curTime = platform_getMilliseconds(); loom_mutex_lock(gFileScannerLock); // Update the pending list with all the stuff we've seen. for (UTsize i = 0; i < deltas->size(); i++) { // Get the delta. const FileEntryDelta& fed = deltas->at(i); // If it's removal, we don't currently send a notification. if (fed.action == FileEntryDelta::Removed) { continue; } // If it's not whitelisted, ignore it. if (!checkInWhitelist(fed.path)) { continue; } // Note it in the pending modification list. bool sawInList = false; for (UTsize i = 0; i < gPendingModifications.size(); i++) { FileModificationNote& fmn = gPendingModifications.at(i); if (strcmp(fmn.path, fed.path.c_str())) { continue; } // Match - update time. lmLogDebug(gAssetAgentLogGroup, "FILE CHANGING - '%s'", fed.path.c_str()); fmn.lastSeenTime = curTime; sawInList = true; } if (!sawInList) { FileModificationNote fmn; fmn.path = stringtable_insert(fed.path.c_str()); fmn.lastSeenTime = curTime; gPendingModifications.push_back(fmn); lmLogDebug(gAssetAgentLogGroup, "FILE CHANGED - '%s'", fed.path.c_str()); } } // Now, walk the pending list and send everyone who hasn't been touched for the settling period. // See how many files we're sending and note that state. const int settleTimeMs = 750; int transferStartTime = platform_getMilliseconds(); int totalPendingTransfers = 0; for (UTsize i = 0; i < gPendingModifications.size(); i++) { // Only consider pending items that have aged out. FileModificationNote& fmn = gPendingModifications.at(i); if (curTime - fmn.lastSeenTime < settleTimeMs) { continue; } totalPendingTransfers++; } bool didWeNotifyUserAboutPending = false; for (UTsize i = 0; i < gPendingModifications.size(); i++) { // Only consider pending items that have aged out. FileModificationNote& fmn = gPendingModifications.at(i); if (curTime - fmn.lastSeenTime < settleTimeMs) { continue; } // Make the path canonical. utString filename = fmn.path; char canonicalFile[MAXPATHLEN]; makeAssetPathCanonical(filename.c_str(), canonicalFile); // Note: we don't deal with deleted files properly (by uploading new state) because realpath // only works right when the file exists. So we just skip doing anything about it. // Note we are using gActiveHandlers.size() outside of a lock, but this is ok as it's a word. if ((strstr(canonicalFile, ".loom") || strstr(canonicalFile, ".ls")) && (gActiveHandlers.size() > 0)) { lmLog(gAssetAgentLogGroup, "Changed '%s'", canonicalFile); } if (canonicalFile[0] == 0) { lmLog(gAssetAgentLogGroup, " o Ignoring file missing from the asset folder!"); // Remove from the pending list. gPendingModifications.erase(i); i--; continue; } // Queue the callback. enqueueFileChangeCallback(canonicalFile); // Map the file. void *fileBits = NULL; long fileBitsLength = 0; if (!platform_mapFile(canonicalFile, &fileBits, &fileBitsLength)) { lmLog(gAssetAgentLogGroup, " o Skipping due to file failing to map."); continue; } // Loop over the active sockets. loom_mutex_lock(gActiveSocketsMutex); // Blast it out to all clients. for (UTsize j = 0; j < gActiveHandlers.size(); j++) { // If it's for a specific client then only send to that client. if ((fmn.onlyForClient != -1) && (fmn.onlyForClient != gActiveHandlers[j]->getId())) { continue; } gActiveHandlers[j]->sendFile(canonicalFile, fileBits, fileBitsLength, totalPendingTransfers); // If it has been more than a second, note that we are still working. const int remainingTransferCount = (totalPendingTransfers * gActiveHandlers.size()) - j; if (((platform_getMilliseconds() - transferStartTime) > 2000) && (remainingTransferCount > 1)) { transferStartTime = platform_getMilliseconds(); lmLog(gAssetAgentLogGroup, "Still transferring files. %d to go!", remainingTransferCount - 1); didWeNotifyUserAboutPending = true; } } loom_mutex_unlock(gActiveSocketsMutex); totalPendingTransfers--; // Unmap the file. platform_unmapFile(fileBits); // Remove from the pending list. gPendingModifications.erase(i); i--; } loom_mutex_unlock(gFileScannerLock); if (didWeNotifyUserAboutPending) { lmLog(gAssetAgentLogGroup, "Done transferring files!"); } }
void LSLuaState::cacheAssemblyTypes(Assembly *assembly, utArray<Type *>& types) { // setup assembly type lookup field lua_rawgeti(L, LUA_GLOBALSINDEX, LSASSEMBLYLOOKUP); lua_pushlightuserdata(L, assembly); lua_setfield(L, -2, assembly->getName().c_str()); lua_pop(L, 1); assembly->ordinalTypes = new Type *[types.size() + 1]; for (UTsize j = 0; j < types.size(); j++) { Type *type = types.at(j); assembly->types.insert(type->getName(), type); lmAssert(type->getTypeID() > 0 && type->getTypeID() <= (LSTYPEID)types.size(), "LSLuaState::cacheAssemblyTypes TypeID out of range"); assembly->ordinalTypes[type->getTypeID()] = type; const char *typeName = type->getFullName().c_str(); // fast access cache if (!strcmp(typeName, "system.Object")) { objectType = type; } else if (!strcmp(typeName, "system.Null")) { nullType = type; } else if (!strcmp(typeName, "system.Boolean")) { booleanType = type; } else if (!strcmp(typeName, "system.Number")) { numberType = type; } else if (!strcmp(typeName, "system.String")) { stringType = type; } else if (!strcmp(typeName, "system.Function")) { functionType = type; } else if (!strcmp(typeName, "system.Vector")) { vectorType = type; } lua_rawgeti(L, LUA_GLOBALSINDEX, LSINDEXMEMBERINFONAME); lua_pushlightuserdata(L, type); lua_gettable(L, -2); // cache all members for fast lookup of memberinfo -> pre-interned // lua string (interning strings is the devil's work) if (lua_isnil(L, -1)) { lua_pop(L, 1); utArray<MemberInfo *> members; MemberTypes types; types.method = true; types.field = true; types.property = true; type->findMembers(types, members, false); // cache the type to member info table lua_pushlightuserdata(L, type); lua_pushstring(L, type->getName()); lua_settable(L, -3); for (UTsize i = 0; i < members.size(); i++) { MemberInfo *mi = members.at(i); lua_pushlightuserdata(L, mi); lua_pushstring(L, mi->getName()); lua_settable(L, -3); } } else { lua_pop(L, 1); } lua_pop(L, 1); // if we weren't cached during assembly load, cache now if (!typeCache.get(type->getFullName())) { typeCache.insert(type->getFullName(), type); } } lmAssert(nullType, "LSLuaState::cacheAssemblyTypes - system.Null not found"); lmAssert(booleanType, "LSLuaState::cacheAssemblyTypes - system.Boolean not found"); lmAssert(numberType, "LSLuaState::cacheAssemblyTypes - system.Number not found"); lmAssert(stringType, "LSLuaState::cacheAssemblyTypes - system.String not found"); lmAssert(functionType, "LSLuaState::cacheAssemblyTypes - system.Function not found"); lmAssert(vectorType, "LSLuaState::cacheAssemblyTypes - system.Vector not found"); }
void addVertex(unsigned int fi, unsigned int bindex, const akMeshLoader::TempVert& ref) { utArray<float> uvs; for(int j=0; j<AK_UV_MAX; j++) { uvs.push_back(ref.uv[j][0]); uvs.push_back(ref.uv[j][1]); } UTuint32 id = item->addVertex(ref.co, ref.no, ref.vcol, uvs); idxmap.push_back(bindex); // vgroups if(m_bmesh->dvert) { Blender::MDeformVert& dv = m_bmesh->dvert[bindex]; for(int j=0; j<dv.totweight; j++) { UTuint32 vgi = dv.dw[j].def_nr; if( vgi < item->getNumVertexGroups() ) { akVertexGroup* vg = item->getVertexGroup(vgi); vg->add(id, dv.dw[j].weight); } } } // morphtargets if(m_bmesh->key) { Blender::KeyBlock* bkb = (Blender::KeyBlock*)m_bmesh->key->block.first; // skip first shape key (basis) int mti=0; if(bkb) bkb = bkb->next; while(bkb) { if(bkb->type == KEY_RELATIVE) { Blender::KeyBlock* basis = (Blender::KeyBlock*)m_bmesh->key->block.first; for(int i=0; basis && i<bkb->relative; i++) basis = basis->next; if(basis) { //akMorphTarget* mt = item->getMorphTarget(bkb->name); akMorphTarget* mt = item->getMorphTarget(mti); float* kpos = (float*)bkb->data; float* bpos = (float*)basis->data; akVector3 k(kpos[3*bindex+0], kpos[3*bindex+1], kpos[3*bindex+2]); akVector3 b(bpos[3*bindex+0], bpos[3*bindex+1], bpos[3*bindex+2]); k = k-b; btAlignedObjectArray<akVector3>& norms = shapekeysnormals->at(mti); akVector3 normal(0,0,0); const Blender::MFace& bface = m_bmesh->mface[fi]; if(bface.flag & ME_SMOOTH) { utArray<UTuint32>& smoothfaces = smoothfacesarray->at(bindex); for (int j = 0; j< smoothfaces.size(); j++) { UTuint32 bface2id = smoothfaces[j]; normal += norms.at(bface2id); } normal = normalize(normal); } else { normal = norms.at(fi); } normal = normal - ref.no; if(!akFuzzyT(lengthSqr(k), 1e-10f) || !akFuzzyT(lengthSqr(normal), 1e-10f)) mt->add(id, k, normal); mti++; } } bkb = bkb->next; } } }