int main(int argc, char** argv) { #ifdef WIN32 const Vector<String>& arguments = ParseArguments(GetCommandLineW()); #else const Vector<String>& arguments = ParseArguments(argc, argv); #endif bool dumpApiMode = false; String outputFile; if (arguments.Size() < 1) ErrorExit("Usage: ScriptCompiler <input file> [resource path for includes]\n" " ScriptCompiler -dumpapi [output file]"); else { if (arguments[0] != "-dumpapi") outputFile = arguments[0]; else { dumpApiMode = true; if (arguments.Size() > 1) outputFile = arguments[1]; } } SharedPtr<Context> context(new Context()); // Note: creating the Engine registers most subsystems which don't require engine initialization SharedPtr<Engine> engine(new Engine(context)); context->RegisterSubsystem(new Script(context)); Log* log = context->GetSubsystem<Log>(); // Register Log subsystem manually if compiled without logging support if (!log) { context->RegisterSubsystem(new Log(context)); log = context->GetSubsystem<Log>(); } log->SetLevel(LOG_WARNING); log->SetTimeStamp(false); if (!dumpApiMode) { String path, file, extension; SplitPath(outputFile, path, file, extension); ResourceCache* cache = context->GetSubsystem<ResourceCache>(); // Add resource path to be able to resolve includes if (arguments.Size() > 1) cache->AddResourceDir(arguments[1]); else cache->AddResourceDir(cache->GetPreferredResourceDir(path)); if (!file.StartsWith("*")) CompileScript(context, outputFile); else { Vector<String> scriptFiles; context->GetSubsystem<FileSystem>()->ScanDir(scriptFiles, path, file + extension, SCAN_FILES, false); for (unsigned i = 0; i < scriptFiles.Size(); ++i) CompileScript(context, path + scriptFiles[i]); } } else { if (!outputFile.Empty()) { log->SetQuiet(true); log->Open(outputFile); } // If without output file, dump to stdout instead context->GetSubsystem<Script>()->DumpAPI(); } return EXIT_SUCCESS; }
bool Animation2D::Load(Deserializer& source) { frameEndTimes_.Clear(); frameSprites_.Clear(); SharedPtr<XMLFile> xmlFile(new XMLFile(context_)); if(!xmlFile->Load(source)) { LOGERROR("Could not load animation"); return false; } SetMemoryUse(source.GetSize()); XMLElement rootElem = xmlFile->GetRoot("Animation"); if (!rootElem) { LOGERROR("Invalid animation"); return false; } ResourceCache* cache = GetSubsystem<ResourceCache>(); XMLElement keyFrameElem = rootElem.GetChild("Frame"); if (!keyFrameElem) { LOGERROR("Could not found key frame"); return false; } float endTime = 0.0f; while (keyFrameElem) { endTime += keyFrameElem.GetFloat("duration"); frameEndTimes_.Push(endTime); SharedPtr<Sprite2D> sprite; Vector<String> names = keyFrameElem.GetAttribute("sprite").Split('@'); if (names.Size() == 1) sprite = cache->GetResource<Sprite2D>(names[0]); else if (names.Size() == 2) { SpriteSheet2D* spriteSheet = cache->GetResource<SpriteSheet2D>(names[0]); if (!spriteSheet) { LOGERROR("Could not get sprite speet"); return false; } sprite = spriteSheet->GetSprite(names[1]); } if (!sprite) { LOGERROR("Could not get sprite"); return false; } frameSprites_.Push(sprite); keyFrameElem = keyFrameElem.GetNext("Frame"); } return true; }
bool DynamicNavigationMesh::Build() { ATOMIC_PROFILE(BuildNavigationMesh); // Release existing navigation data and zero the bounding box ReleaseNavigationMesh(); if (!node_) return false; if (!node_->GetWorldScale().Equals(Vector3::ONE)) ATOMIC_LOGWARNING("Navigation mesh root node has scaling. Agent parameters may not work as intended"); Vector<NavigationGeometryInfo> geometryList; CollectGeometries(geometryList); if (geometryList.Empty()) return true; // Nothing to do // Build the combined bounding box for (unsigned i = 0; i < geometryList.Size(); ++i) boundingBox_.Merge(geometryList[i].boundingBox_); // Expand bounding box by padding boundingBox_.min_ -= padding_; boundingBox_.max_ += padding_; { ATOMIC_PROFILE(BuildNavigationMesh); // Calculate number of tiles int gridW = 0, gridH = 0; float tileEdgeLength = (float)tileSize_ * cellSize_; rcCalcGridSize(&boundingBox_.min_.x_, &boundingBox_.max_.x_, cellSize_, &gridW, &gridH); numTilesX_ = (gridW + tileSize_ - 1) / tileSize_; numTilesZ_ = (gridH + tileSize_ - 1) / tileSize_; // Calculate max. number of tiles and polygons, 22 bits available to identify both tile & polygon within tile unsigned maxTiles = NextPowerOfTwo((unsigned)(numTilesX_ * numTilesZ_)) * maxLayers_; unsigned tileBits = 0; unsigned temp = maxTiles; while (temp > 1) { temp >>= 1; ++tileBits; } unsigned maxPolys = (unsigned)(1 << (22 - tileBits)); dtNavMeshParams params; rcVcopy(params.orig, &boundingBox_.min_.x_); params.tileWidth = tileEdgeLength; params.tileHeight = tileEdgeLength; params.maxTiles = maxTiles; params.maxPolys = maxPolys; navMesh_ = dtAllocNavMesh(); if (!navMesh_) { ATOMIC_LOGERROR("Could not allocate navigation mesh"); return false; } if (dtStatusFailed(navMesh_->init(¶ms))) { ATOMIC_LOGERROR("Could not initialize navigation mesh"); ReleaseNavigationMesh(); return false; } dtTileCacheParams tileCacheParams; memset(&tileCacheParams, 0, sizeof(tileCacheParams)); rcVcopy(tileCacheParams.orig, &boundingBox_.min_.x_); tileCacheParams.ch = cellHeight_; tileCacheParams.cs = cellSize_; tileCacheParams.width = tileSize_; tileCacheParams.height = tileSize_; tileCacheParams.maxSimplificationError = edgeMaxError_; tileCacheParams.maxTiles = numTilesX_ * numTilesZ_ * maxLayers_; tileCacheParams.maxObstacles = maxObstacles_; // Settings from NavigationMesh tileCacheParams.walkableClimb = agentMaxClimb_; tileCacheParams.walkableHeight = agentHeight_; tileCacheParams.walkableRadius = agentRadius_; tileCache_ = dtAllocTileCache(); if (!tileCache_) { ATOMIC_LOGERROR("Could not allocate tile cache"); ReleaseNavigationMesh(); return false; } if (dtStatusFailed(tileCache_->init(&tileCacheParams, allocator_, compressor_, meshProcessor_))) { ATOMIC_LOGERROR("Could not initialize tile cache"); ReleaseNavigationMesh(); return false; } // Build each tile unsigned numTiles = 0; for (int z = 0; z < numTilesZ_; ++z) { for (int x = 0; x < numTilesX_; ++x) { TileCacheData tiles[TILECACHE_MAXLAYERS]; int layerCt = BuildTile(geometryList, x, z, tiles); for (int i = 0; i < layerCt; ++i) { dtCompressedTileRef tileRef; int status = tileCache_->addTile(tiles[i].data, tiles[i].dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tileRef); if (dtStatusFailed((dtStatus)status)) { dtFree(tiles[i].data); tiles[i].data = 0x0; } } ++numTiles; } for (int x = 0; x < numTilesX_; ++x) tileCache_->buildNavMeshTilesAt(x, z, navMesh_); } // For a full build it's necessary to update the nav mesh // not doing so will cause dependent components to crash, like CrowdManager tileCache_->update(0, navMesh_); ATOMIC_LOGDEBUG("Built navigation mesh with " + String(numTiles) + " tiles"); // Send a notification event to concerned parties that we've been fully rebuilt { using namespace NavigationMeshRebuilt; VariantMap& buildEventParams = GetContext()->GetEventDataMap(); buildEventParams[P_NODE] = node_; buildEventParams[P_MESH] = this; SendEvent(E_NAVIGATION_MESH_REBUILT, buildEventParams); } // Scan for obstacles to insert into us PODVector<Node*> obstacles; GetScene()->GetChildrenWithComponent<Obstacle>(obstacles, true); for (unsigned i = 0; i < obstacles.Size(); ++i) { Obstacle* obs = obstacles[i]->GetComponent<Obstacle>(); if (obs && obs->IsEnabledEffective()) AddObstacle(obs); } return true; } }
void SplitLoops(BlockCFG *base_cfg, Vector<BlockCFG*> *result_cfg_list) { // get the CFG which will eventually become the loop-free outer function CFG. BlockCFG *func_cfg; if (base_cfg->GetId()->Kind() == B_FunctionWhole) { // make an ID for the outer function body. Variable *function_info = base_cfg->GetId()->BaseVar(); function_info->IncRef(); BlockId *outer_id = BlockId::Make(B_Function, function_info); // make the function CFG by cloning the base CFG with the new ID. func_cfg = BlockCFG::Make(outer_id); CopyCFGLocationsVariables(base_cfg, func_cfg); CopyCFGPointsEdges(base_cfg, func_cfg); } else if (base_cfg->GetId()->Kind() == B_Function) { // this call came from a recursive invocation of SplitLoops after we // removed an irreducible loop from the function. func_cfg = base_cfg; } else { // just destructively update the original CFG. base_cfg->IncRef(); func_cfg = base_cfg; } // add a new entry point with a skip edge to the original entry point. // loop splitting breaks if the entry point is marked as a loop head. PPoint entry = func_cfg->GetEntryPoint(); Location *loc = func_cfg->GetPointLocation(entry); loc->IncRef(); PPoint new_entry = func_cfg->AddPoint(loc); PEdge *skip_edge = PEdge::MakeSkip(new_entry, entry); func_cfg->AddEdge(skip_edge); func_cfg->SetEntryPoint(new_entry); // setup the tables we need to do loop splitting. SetupTables(); // compute the points reachable from the entry point. GetEntryReachable(func_cfg); // the real loops in the program with back edges. Vector<PPoint> loops; for (size_t lind = 0; lind < func_cfg->GetLoopHeadCount(); lind++) { PPoint head = func_cfg->GetLoopHead(lind).point; if (GetLoopBackedges(func_cfg, head)) loops.PushBack(head); } // compute reachability and check for irreducible loops. for (size_t lind = 0; lind < func_cfg->GetLoopHeadCount(); lind++) { const LoopHead &head = func_cfg->GetLoopHead(lind); if (GetLoopReachable(func_cfg, head.point)) { // loop is irreducible. // get the loop's irreducible edges. Vector<PEdge*> irreducible_edges; GetLoopBody(func_cfg, head.point, &irreducible_edges); Assert(!irreducible_edges.Empty()); // clone the loop's body and remove the irreducible edges. ReduceLoop(func_cfg, head.point, irreducible_edges); // try again on the modified CFG. CleanupTables(); SplitLoops(func_cfg, result_cfg_list); return; } } // there are no irreducible loops at this point so this should // never have any entries added. Vector<PEdge*> irreducible_edges; // compute loop bodies. for (size_t lind = 0; lind < loops.Size(); lind++) { PPoint head = loops[lind]; GetLoopBody(func_cfg, head, &irreducible_edges); Assert(irreducible_edges.Empty()); } // construct a tree of all the loops. loop A contains loop B // if A != B and the head of B is in the body of A. PPointListHash loop_tree; // split off all the loops in the CFG. make sure we split inner loops // before outer, so that the Loop edges on inner loops will appear in // the split body for outer loops. while (!loops.Empty()) { // find a candidate loop to split. this is one whose loop children // have already been split off and are no longer in the loops list. PPoint loophead = 0; for (size_t lind = 0; lind < loops.Size(); lind++) { bool is_viable = true; for (size_t xlind = 0; xlind < loops.Size(); xlind++) { if (xlind == lind) continue; Assert(loops[lind] != loops[xlind]); if (body_table->Lookup(PPointPair(loops[lind], loops[xlind]))) { is_viable = false; break; } } if (is_viable) { loophead = loops[lind]; loops[lind] = loops.Back(); loops.PopBack(); break; } } Assert(loophead); BlockCFG *loop_cfg = SplitSingleLoop(loophead, loops, func_cfg); result_cfg_list->PushBack(loop_cfg); } // clear out the loopheads, we don't want them around anymore. func_cfg->ClearLoopHeads(); // trim unreachable points in the function CFG (i.e. bodies of loops that // now redirect to point zero), collapse skips and topo sort. TrimUnreachable(func_cfg, true); TopoSortCFG(func_cfg); result_cfg_list->PushBack(func_cfg); CleanupTables(); // fill in any loop parents for the inner loop CFGs, and make sure the // result CFGs are ordered correctly, with inner loops before outer loops // and the outer function. for (size_t cind = 0; cind < result_cfg_list->Size(); cind++) { BlockCFG *cfg = result_cfg_list->At(cind); for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) { if (PEdgeLoop *edge = cfg->GetEdge(eind)->IfLoop()) { BlockId *target_id = edge->GetLoopId(); bool found_target = false; for (size_t xcind = 0; xcind < cind; xcind++) { BlockCFG *xcfg = result_cfg_list->At(xcind); if (xcfg->GetId() == target_id) { found_target = true; cfg->GetId()->IncRef(); BlockPPoint where(cfg->GetId(), edge->GetSource()); xcfg->AddLoopParent(where); // mark the isomorphic points in the parent CFG. GetLoopIsomorphicPoints(cfg, edge, xcfg); break; } } Assert(found_target); } } } // assign the final names to the various loop CFGs. FillLoopNames(func_cfg, "loop", *result_cfg_list); }
// remove the irreducible entry edges on loophead by cloning the body // of loophead, redirecting the irreducible edges to that cloned body, // and directing the back edges of the cloned loop back to the entry // of the real loop. destructively modifies cfg. void ReduceLoop(BlockCFG *cfg, PPoint loophead, const Vector<PEdge*> &irreducible_edges) { PPointListHash remapping; Vector<size_t> old_entry_indexes; Vector<size_t> old_exit_indexes; Vector<size_t> old_back_indexes; CloneLoopBody(cfg, loophead, &remapping, cfg, &old_entry_indexes, &old_exit_indexes, &old_back_indexes); // replace the irreducible entry edges with edges into the // corresponding point in the new loop. for (size_t iind = 0; iind < irreducible_edges.Size(); iind++) { PEdge *irr_edge = irreducible_edges[iind]; bool found_index = false; for (size_t oind = 0; oind < old_entry_indexes.Size(); oind++) { size_t entry_index = old_entry_indexes[oind]; PEdge *old_edge = cfg->GetEdge(entry_index); if (old_edge == irr_edge) { Assert(!found_index); found_index = true; PPoint source = old_edge->GetSource(); PPoint target = old_edge->GetTarget(); PPoint new_target = remapping.LookupSingle(target); PEdge *new_edge = PEdge::ChangeEdge(old_edge, source, new_target); cfg->SetEdge(entry_index, new_edge); } } Assert(found_index); } // add the old exit edges for the new loop. for (size_t oind = 0; oind < old_exit_indexes.Size(); oind++) { PEdge *old_edge = cfg->GetEdge(old_exit_indexes[oind]); PPoint source = old_edge->GetSource(); PPoint target = old_edge->GetTarget(); PPoint new_source = remapping.LookupSingle(source); PEdge *new_edge = PEdge::ChangeEdge(old_edge, new_source, target); cfg->AddEdge(new_edge); } // add the old back edges as edges to the entry point of the old loop. for (size_t oind = 0; oind < old_back_indexes.Size(); oind++) { PEdge *old_edge = cfg->GetEdge(old_back_indexes[oind]); PPoint source = old_edge->GetSource(); PPoint target = old_edge->GetTarget(); PPoint new_source = remapping.LookupSingle(source); Assert(target == loophead); PEdge *new_edge = PEdge::ChangeEdge(old_edge, new_source, target); cfg->AddEdge(new_edge); } // add any loopheads that may have been duplicated within the cloned loop. // note that the new loophead does not have any incoming edges and will // get trimmed by TrimUnreachable(). for (size_t lind = 0; lind < cfg->GetLoopHeadCount(); lind++) { const LoopHead &head = cfg->GetLoopHead(lind); Vector<PPoint> *new_point_list = remapping.Lookup(head.point, false); if (new_point_list) { Assert(new_point_list->Size() == 1); LoopHead new_head(new_point_list->At(0), head.end_location); if (head.end_location) head.end_location->IncRef(); cfg->AddLoopHead(new_head.point, new_head.end_location); } } // trim unreachable portions of the cfg, but do not collapse skip edges. TrimUnreachable(cfg, false); }
void SymSparseLinSOE::setX(const Vector &x) { if (x.Size() == size && vectX != 0) *vectX = x; }
// mark the trivial/redundant assertions in the specified list. void MarkRedundantAssertions(BlockMemory *mcfg, Vector<AssertInfo> &asserts) { BlockCFG *cfg = mcfg->GetCFG(); // assertions are marked redundant in two passes: // 1. for each path reaching the assertion, the validity of the assertion is // implied by one or more prior or future assertions. // this pass also picks up assertions which trivially hold, where the // assertion is valid due to the conditions along the paths themselves. // 2. there is an isomorphic assertion within an inner loop. it is // sufficient to check just the inner assertion. // implication works differently for invariants vs. other assertions, // since the invariant condition will be asserted at block exit. // for regular assertions, an bit is redundant if (guard ==> bit) // is implied by the (oguard ==> obit) for other assertions: // VALID((oguard ==> obit) ==> (guard ==> bit)) // !SAT(!((oguard ==> obit) ==> (guard ==> bit))) // !SAT(!(!(oguard ==> obit) || (guard ==> bit))) // !SAT((oguard ==> obit) && !(guard ==> bit)) // !SAT((oguard ==> obit) && !(!guard || bit)) // !SAT((oguard ==> obit) && guard && !bit) // for invariants, a bit is redundant if guard implies the oguard // for other invariants with the same asserted bit: // VALID(guard ==> oguard) // !SAT(!(guard ==> oguard)) // !SAT(!(!guard || oguard)) // !SAT(guard && !oguard) Solver *solver = new Solver("redundant"); for (size_t ind = 0; ind < asserts.Size(); ind++) { AssertInfo &info = asserts[ind]; solver->PushContext(); Assert(info.cls == ASC_Check); // assert guard. Bit *guard = mcfg->GetGuard(info.point); solver->AddAssert(0, guard); if (info.kind != ASK_Invariant) { // assert !bit. Bit *not_bit = Bit::MakeNot(info.bit); Bit *result_not_bit; mcfg->TranslateBit(TRK_Point, info.point, not_bit, &result_not_bit); solver->AddAssert(0, result_not_bit); } if (!solver->IsSatisfiable()) { // the assert is tautological or is proved by the guard, thus trivial. info.cls = ASC_Trivial; solver->PopContext(); continue; } // assert the remaining assertions in the summary hold. for (size_t aind = 0; aind < asserts.Size(); aind++) { const AssertInfo &oinfo = asserts[aind]; // skip this assertion itself. if (info.point == oinfo.point && info.bit == oinfo.bit) continue; // skip assertions already marked as trivial or redundant. if (oinfo.cls != ASC_Check) continue; // skip assertions for a different kind than the original. // this avoids interference between the different kinds of assertions, // though it is unlikely to affect whether we actually mark an // assert as redundant. if (oinfo.kind != info.kind) continue; Bit *oguard = mcfg->GetGuard(oinfo.point); if (info.kind == ASK_Invariant) { // only compare with other invariants for the same bit. if (oinfo.bit != info.bit) continue; // assert !oguard Bit *not_oguard = Bit::MakeNot(oguard); solver->AddAssert(0, not_oguard); } else { // assert (oguard ==> obit). Bit *result_obit; mcfg->TranslateBit(TRK_Point, oinfo.point, oinfo.bit, &result_obit); Bit *imply_bit = Bit::MakeImply(oguard, result_obit); solver->AddAssert(0, imply_bit); } } if (!solver->IsSatisfiable()) { // the assert is implied by the remaining assertions, thus redundant. info.cls = ASC_Redundant; } solver->PopContext(); } solver->Clear(); delete solver; for (size_t ind = 0; ind < cfg->GetEdgeCount(); ind++) { PEdgeLoop *loop_edge = cfg->GetEdge(ind)->IfLoop(); if (!loop_edge) continue; for (size_t aind = 0; aind < asserts.Size(); aind++) { AssertInfo &info = asserts[aind]; if (info.cls != ASC_Check) continue; if (cfg->IsLoopIsomorphic(info.point)) { // this assertion's point is isomorphic to a point within the // loop body, so there will be an equivalent loop assertion. info.cls = ASC_Redundant; } } } }
/*---------------------------------------------------------------------------------------------- This is the main interesting method of displaying objects and fragments of them. Here a CmPossibilityList is displayed by displaying its Records. So far we only handle records that are objects of type CmPossibility (or a subclass). A CmPossibility (or derived object) is displayed according to the stored specifications. ----------------------------------------------------------------------------------------------*/ STDMETHODIMP CleCustDocVc::Display(IVwEnv * pvwenv, HVO hvo, int frag) { BEGIN_COM_METHOD; ChkComArgPtr(pvwenv); bool fFlat = m_qcmw->IsFilterActive() || m_qcmw->IsSortMethodActive(); // Constant fragments switch(frag) { case kfrcdSubItem: // Override for special treatment. Assert(false); // sub-items are handled as main items; see below. break; case kfrcdMainItem: // Override for special treatment. { // Get the complete list of the items in the order in which they are displayed. ISilDataAccessPtr qsda; CheckHr(pvwenv->get_DataAccess(&qsda)); RecMainWndPtr qrmw = dynamic_cast<RecMainWnd *>(m_qcmw.Ptr()); HVO hvoMain = qrmw->GetFilterId(); int flidMain = qrmw->GetFilterFlid(); Assert(qrmw); int chvoMain; Vector<HVO> vhvoMain; CheckHr(qsda->get_VecSize(hvoMain, flidMain, &chvoMain)); for (int ihvo = 0; ihvo < chvoMain; ihvo++) { HVO hvoTmp; CheckHr(qsda->get_VecItem(hvoMain, flidMain, ihvo, &hvoTmp)); vhvoMain.Push(hvoTmp); } ITsTextPropsPtr qttp; PossItemInfo * ppii; PossListInfoPtr qpli; m_qlpi->GetPossListAndItem(hvo, m_qlpi->AnalWs(), &ppii, &qpli); int ilevel; ilevel = ppii->GetLevel(qpli); int ipss; for (ipss = 0; ipss < vhvoMain.Size(); ipss++) { if (hvo == vhvoMain[ipss]) break; } Assert(ipss < vhvoMain.Size()); if (fFlat) qttp = m_qttpMainFlat; else if (ilevel > 0) { if (ipss == qpli->GetCount() - 1) qttp = m_qttpSubLast; else qttp = m_qttpSub; // Adjust the indentation to match the current level. ITsPropsBldrPtr qtpb; CheckHr(qttp->GetBldr(&qtpb)); CheckHr(qtpb->SetIntPropValues(ktptPadLeading, ktpvMilliPoint, (ilevel * kdzmpInch / 5))); // indent 1/5" per level CheckHr(qtpb->GetTextProps(&qttp)); } else if (ipss == 0) // first item qttp = m_qttpMainFirst; else if (ipss == qpli->GetCount() - 1) qttp = m_qttpMainLast; else qttp = m_qttpMain; CheckHr(pvwenv->put_Props(qttp)); BodyOfRecord(pvwenv, hvo, qttp); break; } default: return SuperClass::Display(pvwenv, hvo, frag); } return S_OK; END_COM_METHOD(g_fact1, IID_IVwViewConstructor) }
/*---------------------------------------------------------------------------------------------- Set the list of style objects to the (fake) styles attribute of StText. Called from the XML import routine. ----------------------------------------------------------------------------------------------*/ HRESULT WpStylesheet::AddLoadedStyles(HVO * rghvoNew, int chvo, int hvoNextStyle) { int cst; CheckHr(m_qsda->get_VecSize(khvoText, kflidStText_Styles, &cst)); WpDaPtr wpda = dynamic_cast<WpDa *>(m_qsda.Ptr()); // Note: we are clobbering any existing styles. HRESULT hr = wpda->CacheReplace(khvoText, kflidStText_Styles, 0, cst, rghvoNew, chvo); m_vhcStyles.Clear(); bool fFoundNormal= false; for (int ihvo = 0; ihvo < chvo; ihvo++) { HvoClsid hc; hc.clsid = kclidStStyle; hc.hvo = rghvoNew[ihvo]; m_vhcStyles.Push(hc); SmartBstr sbstrName; CheckHr(m_qsda->get_UnicodeProp(hc.hvo, kflidStStyle_Name, &sbstrName)); StrUni stuName(sbstrName.Chars()); if (stuName == g_pszwStyleNormal) fFoundNormal = true; } m_hvoNextStyle = max(m_hvoNextStyle, hvoNextStyle); if (!fFoundNormal) AddNormalParaStyle(); #if 0 // Old code for deleting only duplicates. int cstNew; CheckHr(m_qsda->get_VecSize(khvoText, kflidStText_Styles, &cstNew)); Assert(cstNew == cst + chvo); // If there are any styles with duplicate names, delete the first // (previously existing) one. Vector<int> vihvoDelete; Vector<StrUni> vstuStyleNames; for (ihvo = 0; ihvo < m_vhcStyles.Size(); ihvo++) { SmartBstr sbstrName; CheckHr(m_qsda->get_UnicodeProp(m_vhcStyles[ihvo].hvo, kflidStStyle_Name, &sbstrName)); StrUni stu(sbstrName.Chars()); vstuStyleNames.Push(stu); } Assert(vstuStyleNames.Size() == m_vhcStyles.Size()); for (ihvo = 0; ihvo < vstuStyleNames.Size() - 1; ihvo++) { for (int ihvo2 = ihvo + 1; ihvo2 < vstuStyleNames.Size(); ihvo2++) { if (vstuStyleNames[ihvo] == vstuStyleNames[ihvo2]) { vihvoDelete.Push(ihvo); break; } } } // Delete the duplicates; do it backwards so the indices stay valid. for (int iihvo = vihvoDelete.Size(); --iihvo >= 0; ) { HVO ihvoToDelete = vihvoDelete[iihvo]; m_vhcStyles.Delete(ihvoToDelete); CheckHr(wpda->CacheReplace(khvoText, kflidStText_Styles, ihvoToDelete, ihvoToDelete+1, NULL, 0)); } CheckHr(m_qsda->get_VecSize(khvoText, kflidStText_Styles, &cstNew)); Assert(cstNew == cst + chvo - vihvoDelete.Size()); #endif return hr; }
int VrmlViewer::drawLine(const Vector &pos1, const Vector &pos2, float V1, float V2) { float x,y,z, r, g, b; (*vrmlFile) << "Shape { geometry IndexedLineSet "; (*vrmlFile) << "{ coord Coordinate { \n\t\t point [\n"; int size = pos1.Size(); if (size == 1) { x = pos1(0); y = 0; z = 0; } else if (size == 2) { x = pos1(0); y = pos1(1); z = 0; } else { x = pos1(0); y = pos1(1); z = pos1(2); } (*vrmlFile) << "\t\t\t " << x << " " << y << " " << z << ",\n"; size = pos2.Size(); if (size == 1) { x = pos2(0); y = 0; z = 0; } else if (size == 2) { x = pos2(0); y = pos2(1); z = 0; } else { x = pos2(0); y = pos2(1); z = pos2(2); } (*vrmlFile) << "\t\t\t " << x << " " << y << " " << z << " ] }\n"; (*vrmlFile) << " coordIndex [ 0 1 ]\n"; (*vrmlFile) << " colorPerVertex TRUE\n "; (*vrmlFile) << " color Color { \n\t color [\n"; r = theMap->getRed(V1); g = theMap->getGreen(V1); b = theMap->getBlue(V1); (*vrmlFile) << "\t\t\t " << r << " " << g << " " << b << ",\n"; r = theMap->getRed(V2); g = theMap->getGreen(V2); b = theMap->getBlue(V2); (*vrmlFile) << "\t\t\t " << r << " " << g << " " << b << " ] \n }}}\n"; return 0; }
int main() { // Now do the LU decomposition of this problem (NEW 2006) long J = 20; cout << "Number of space subdivisions: "; cin >> J; cout << "Number of time subdivisions: "; long N; cin >> N; double h = 1.0 / double(J); double k = 1.0 / double(N); /////// LU STUFF FIRST //////////// // Constructors with size, start index and value (Diagonals of matrix) // N.B. This is the Crank Nicolson scheme double A = 0.0; // LHS double B = 1.0; // RHS double lambda = k /(h*h); cout << "Lambda " << lambda; // J intervals, thus J-1 UNKNOWN internal points Vector<double, long> a(J-1,1, -lambda); Vector<double, long> b(J-1,1, (2.0 + 2.0*lambda)); Vector<double, long> c(J-1,1, -lambda); Vector<double, long> r(J-1, 1); // Right-hand side NOT CONSTANT ANYMORE // Create the mesh Range<double> range(A, B); Vector<double, long> XARR = range.mesh(J); print(XARR); // Initial condition Vector<double, long> vecOld (XARR.Size(), XARR.MinIndex()); // At time n // print(vecOld); // For LU Vector<double, long> vecNew(XARR.Size(), XARR.MinIndex()); // At time n+1 // For DoubleSweep Vector<double, long> vecNew2(XARR.Size(), XARR.MinIndex()); // At time n+1 vecOld[vecOld.MinIndex()] = 0.0; vecOld[vecOld.MaxIndex()] = 0.0; for (long j = vecOld.MinIndex()+1; j <= vecOld.MaxIndex()-1; j++) { vecOld[j] = InitialCondition(XARR[j]); } print(vecOld); // printOneExcel(XARR, vecOld); // OK, let's start double current = k; long n = 1; L2: // Update at new time level n+1 vecNew[vecNew.MinIndex()] = 0.0; vecNew[vecNew.MaxIndex()] = 0.0; vecNew2[vecNew2.MinIndex()] = 0.0; vecNew2[vecNew2.MaxIndex()] = 0.0; for (long jj = r.MinIndex(); jj <= r.MaxIndex(); jj++) { // Examine!! indices in vecOld, it's tricky but CORRECT r[jj] = (lambda*vecOld[jj]) + (2.0 - (2.0*lambda))*vecOld[jj+1] + (lambda*vecOld[jj+2]); } // Calculate RHS LUTridiagonalSolver<double, long> mySolver(a, b, c, r); // cout << "coeffs"; /* print(a); print(b); print(c); print(r); int rr; cin >> rr;*/ // The matrix must be diagonally dominant; we call the // assert macro and the programs stops /// assert (mySolver.diagonallyDominant() == true); Vector<double, long> result = mySolver.solve(); // print(result); for (long ii = vecNew.MinIndex()+1; ii <= vecNew.MaxIndex()-1;ii++) { vecNew[ii] = result[ii-1]; } vecOld = vecNew; // print(vecNew); // int ff; cin >> ff; // print(XARR); // print(vecNew); // int y; cin >> y; //printOneExcel(XARR, vecNew); double LHS = vecNew2[vecNew2.MinIndex()]; double RHS = vecNew2[vecNew2.MaxIndex()]; DoubleSweep<double, long> mySweep( a, b, c, r, LHS, RHS); Vector<double, long> result2 = mySweep.solve(); // print(result2); // cout << "double"; int fff; cin >> fff; for (long p = vecNew2.MinIndex()+1;p <= vecNew2.MaxIndex()-1; p++) { vecNew2[p] = result2[p-1]; } vecOld = vecNew2; n++; if (n < N) { current += k; goto L2; } cout << "\n Difference " << lInfinityNorm(vecNew, vecNew2); //print(vecNew2); //print(vecNew); printOneExcel(XARR, vecNew, string("LU")); printOneExcel(XARR, vecNew2, string("Sweep")); return 0; }
bool feasible_motion2::solve_inverse_kinematic(sKinematics *_Chain,IKGroupSolver _Solver, Vector _q_in, Vector &_q_out, Matrix _Final_transformation) { if ((_Final_transformation.RowSize()!=4)&&(_Final_transformation.ColumnSize()!=4)) { return false; cout<<"The size of the target is not correct"<<endl; } if ((_q_in.Size()!=7)) { return false; cout<<"The size of the target is not correct"<<endl; } if ((_Final_transformation.RowSize()!=4)&&(_Final_transformation.ColumnSize()!=4)) { return false; cout<<"The size of the target is not correct"<<endl; } int _AXIS_X=0; int _AXIS_Y=1; int _AXIS_Z=2; int _KUKA_DOF=7; Vector _Pos; _Pos.Resize(3); Vector _DirY; _DirY.Resize(3); Vector _DirZ; _DirZ.Resize(3); Vector _TargetPos; _TargetPos.Resize(3); Vector _TargetDirY; _TargetDirY.Resize(3); Vector _TargetDirZ; _TargetDirZ.Resize(3); Vector _FinalPos; _FinalPos.Resize(3); Vector _FinalDirY; _FinalDirY.Resize(3); Vector _FinalDirZ; _FinalDirZ.Resize(3); Vector _JointDesPos; _JointDesPos.Resize(7); Vector _Joints; _Joints.Resize(7); Vector _JointDesVel; _JointDesVel.Resize(7); Vector _TargetVelocity; _TargetVelocity.Resize(9); Vector _error; _error.Resize(9); Vector _JointVelLimitsDn; _JointVelLimitsDn.Resize(_KUKA_DOF); Vector _JointVelLimitsUp; _JointVelLimitsUp.Resize(_KUKA_DOF); double _Dt=0.001; Matrix _Jacobian3; _Jacobian3.Resize(3,_KUKA_DOF); Matrix _Jacobian9; _Jacobian9.Resize(9,KUKA_DOF); Matrix _JacobianDirY; _JacobianDirY.Resize(3,_KUKA_DOF); Matrix _JacobianDirZ; _JacobianDirZ.Resize(3,_KUKA_DOF); for(int i=0;i<_KUKA_DOF;i++){ _JointVelLimitsDn(i) = _Chain->getMin(i); _JointVelLimitsUp(i) = _Chain->getMax(i); } _Solver.SetLimits(_JointVelLimitsDn,_JointVelLimitsUp); _Joints=_q_in; _Chain->setJoints(_Joints.Array()); _Chain->getEndPos(_Pos.Array()); _Chain->getEndDirAxis(_AXIS_Y, _DirY.Array()); _Chain->getEndDirAxis(_AXIS_Z, _DirZ.Array()); _FinalPos(0)=_Final_transformation(0,3); _FinalPos(1)=_Final_transformation(1,3); _FinalPos(2)=_Final_transformation(2,3); _FinalDirY(0)=_Final_transformation(0,1); _FinalDirY(1)=_Final_transformation(1,1); _FinalDirY(2)=_Final_transformation(2,1); _FinalDirZ(0)=_Final_transformation(0,2); _FinalDirZ(1)=_Final_transformation(1,2); _FinalDirZ(2)=_Final_transformation(2,2); _error(0)=_Pos(0)-_FinalPos(0); _error(1)=_Pos(1)-_FinalPos(1); _error(2)=_Pos(2)-_FinalPos(2); _error(3)=_DirY(0)-_FinalDirY(0); _error(4)=_DirY(1)-_FinalDirY(1); _error(5)=_DirY(2)-_FinalDirY(2); _error(6)=_DirZ(0)-_FinalDirZ(0); _error(7)=_DirZ(1)-_FinalDirZ(1); _error(8)=_DirZ(2)-_FinalDirZ(2); double _old_error=1000; while (_error.Norm()<_old_error) { _Chain->setJoints(_Joints.Array()); _Chain->getEndPos(_Pos.Array()); _Chain->getEndDirAxis(_AXIS_Y, _DirY.Array()); _Chain->getEndDirAxis(_AXIS_Z, _DirZ.Array()); _Chain->getJacobianPos(_Jacobian3); _Chain->getJacobianDirection(_AXIS_Y, _JacobianDirY); _Chain->getJacobianDirection(_AXIS_Z, _JacobianDirZ); for(int i=0; i<3; i++){ _Jacobian9.SetRow(_Jacobian3.GetRow(i) , i ); _Jacobian9.SetRow(_JacobianDirY.GetRow(i), i+3); _Jacobian9.SetRow(_JacobianDirZ.GetRow(i), i+6); } _TargetVelocity.SetSubVector(0, (_FinalPos -_Pos ) / _Dt ); _TargetVelocity.SetSubVector(3, (_FinalDirY-_DirY) / _Dt ); _TargetVelocity.SetSubVector(6, (_FinalDirZ-_DirZ) / _Dt ); _Solver.SetJacobian(_Jacobian9); _Solver.SetTarget(_TargetVelocity, 0); _Solver.Solve(); _JointDesVel = _Solver.GetOutput(); _JointDesPos = _Joints + _JointDesVel*_Dt; _Joints=_JointDesPos; mJointDesPos=_JointDesPos; _old_error=_error.Norm(); _Chain->setJoints(_Joints.Array()); _Chain->getEndPos(_Pos.Array()); _Chain->getEndDirAxis(_AXIS_Y, _DirY.Array()); _Chain->getEndDirAxis(_AXIS_Z, _DirZ.Array()); _error(0)=_Pos(0)-_FinalPos(0); _error(1)=_Pos(1)-_FinalPos(1); _error(2)=_Pos(2)-_FinalPos(2); _error(3)=_DirY(0)-_FinalDirY(0); _error(4)=_DirY(1)-_FinalDirY(1); _error(5)=_DirY(2)-_FinalDirY(2); _error(6)=_DirZ(0)-_FinalDirZ(0); _error(7)=_DirZ(1)-_FinalDirZ(1); _error(8)=_DirZ(2)-_FinalDirZ(2); cout<<"Pos "<<(_Pos-_FinalPos).Norm2()<<" "<<(_DirY-_FinalDirY).Norm2() <<" "<<(_DirZ-_FinalDirZ).Norm2()<<endl; } _q_out=_JointDesPos; return true; }
int AlgorithmIncrements::plotData(const Vector &X, const Vector &B) { int size = X.Size(); if (size < 2) return 0; /* * first pass plot the unbalance (B in the SOE): * 1) set the port window to be upper half * 2) determine bounds * 3) draw axis and bounds values * 4) draw points */ theRenderer->clearImage(); theRenderer->setPortWindow(-1.0, 1.0, 0.0, 1.0); // use the whole window double xMin, xMax, yMin, yMax; xMin = 0.0; xMax = B.Size(); yMin = 0.0; yMax = 0.0; int i; for (i=0; i<size; i++) { double value = B(i); if (value < yMin) yMin = value; if (value > yMax) yMax = value; } if (-yMin > yMax) yMax = -yMin; else yMin = -yMax; // set the window bounds NOTE small border around the edges double xBnd = (xMax-xMin)/10; double yBnd = (yMax-yMin)/10; theRenderer->setViewWindow(xMin-xBnd,xMax+xBnd,yMin-yBnd,yMax+yBnd); theRenderer->startImage(); static Vector pt1(3); static Vector pt2(3); pt1(2) = 0.0; pt2(2) = 0.0; // draw the x axis pt1(0) = xMin; pt2(0) = xMax; pt1(1) = 0.0; pt2(1) = 0.0; theRenderer->drawLine(pt1, pt2, 0.0, 0.0); // draw the y axis pt1(0) = 0.0; pt2(0) = 0.0; pt1(1) = yMin; pt2(1) = yMax; theRenderer->drawLine(pt1, pt2, 0.0, 0.0); static char theText[20]; if (yMin != 0.0 && -100 *yMin > yMax) { sprintf(theText,"%.2e",yMin); theRenderer->drawText(pt1, theText, strlen(theText)); } if (yMax != 0.0) { sprintf(theText,"%.2e",yMax); theRenderer->drawText(pt2, theText, strlen(theText)); } pt1(0) = 1; pt1(1) = B(0); for (i=1; i<size; i++) { pt2(0) = i+1; pt2(1) = B(i); theRenderer->drawLine(pt1, pt2, 1.0, 1.0); pt1(0) = pt2(0); pt1(1) = pt2(1); } theRenderer->doneImage(); /* * first pass plot the unbalance (B in the SOE): * 1) set the port window to be upper half * 2) determine bounds * 3) draw axis and bounds values * 4) draw points */ // theRenderer->clearImage(); theRenderer->setPortWindow(-1.0, 1.0, -1.0, 0.0); // use the whole window xMin = 0.0; xMax = X.Size(); yMin = 0.0; yMax = 0.0; for (i=0; i<size; i++) { double value = X(i); if (value < yMin) yMin = value; if (value > yMax) yMax = value; } if (-yMin > yMax) yMax = -yMin; else yMin = -yMax; // set the window bounds NOTE small border around the edges xBnd = (xMax-xMin)/10; yBnd = (yMax-yMin)/10; theRenderer->setViewWindow(xMin-xBnd,xMax+xBnd,yMin-yBnd,yMax+yBnd); theRenderer->startImage(); pt1(2) = 0.0; pt2(2) = 0.0; // draw the x axis pt1(0) = xMin; pt2(0) = xMax; pt1(1) = 0.0; pt2(1) = 0.0; theRenderer->drawLine(pt1, pt2, 0.0, 0.0); // draw the y axis pt1(0) = 0.0; pt2(0) = 0.0; pt1(1) = yMin; pt2(1) = yMax; theRenderer->drawLine(pt1, pt2, 0.0, 0.0); if (yMin != 0.0 && -100 *yMin > yMax) { sprintf(theText,"%.2e",yMin); theRenderer->drawText(pt1, theText, strlen(theText)); } if (yMax != 0.0) { sprintf(theText,"%.2e",yMax); theRenderer->drawText(pt2, theText, strlen(theText)); } pt1(0) = 1; pt1(1) = X(0); for (i=1; i<size; i++) { pt2(0) = i+1; pt2(1) = X(i); theRenderer->drawLine(pt1, pt2, 1.0, 1.0); pt1(0) = pt2(0); pt1(1) = pt2(1); } theRenderer->doneImage(); return 0; }
void UmfpackGenLinSOE::setX(const Vector &x) { if (x.Size() == size && vectX != 0) *vectX = x; }
void CompileVariation(CompiledVariation* variation) { IncludeHandler includeHandler; PODVector<D3D_SHADER_MACRO> macros; // Insert variation-specific and global defines for (unsigned i = 0; i < variation->defines_.Size(); ++i) { D3D_SHADER_MACRO macro; macro.Name = variation->defines_[i].CString(); macro.Definition = variation->defineValues_[i].CString(); macros.Push(macro); } for (unsigned i = 0; i < defines_.Size(); ++i) { D3D_SHADER_MACRO macro; macro.Name = defines_[i].CString(); macro.Definition = defineValues_[i].CString(); macros.Push(macro); } D3D_SHADER_MACRO endMacro; endMacro.Name = 0; endMacro.Definition = 0; macros.Push(endMacro); LPD3DBLOB shaderCode = NULL; LPD3DBLOB errorMsgs = NULL; // Set the profile, entrypoint and flags according to the shader being compiled String profile; String entryPoint; unsigned flags = D3DCOMPILE_OPTIMIZATION_LEVEL3; if (variation->type_ == VS) { entryPoint = "VS"; if (!useSM3_) profile = "vs_2_0"; else profile = "vs_3_0"; } else { entryPoint = "PS"; if (!useSM3_) profile = "ps_2_0"; else { profile = "ps_3_0"; flags |= D3DCOMPILE_PREFER_FLOW_CONTROL; } } // Compile using D3DCompiler HRESULT hr = D3DCompile(hlslCode_.CString(), hlslCode_.Length(), NULL, ¯os.Front(), &includeHandler, entryPoint.CString(), profile.CString(), flags, 0, &shaderCode, &errorMsgs); if (FAILED(hr)) { variation->errorMsg_ = String((const char*)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); compileFailed_ = true; } else { BYTE const *const bufData = static_cast<BYTE *>(shaderCode->GetBufferPointer()); SIZE_T const bufSize = shaderCode->GetBufferSize(); MOJOSHADER_parseData const *parseData = MOJOSHADER_parse("bytecode", bufData, bufSize, NULL, 0, NULL, 0, NULL, NULL, NULL); CopyStrippedCode(variation->byteCode_, shaderCode->GetBufferPointer(), shaderCode->GetBufferSize()); if (!variation->name_.Empty()) PrintLine("Compiled shader variation " + variation->name_ + ", code size " + String(variation->byteCode_.Size())); else PrintLine("Compiled base shader variation, code size " + String(variation->byteCode_.Size())); // Print warnings if any if (errorMsgs && errorMsgs->GetBufferSize()) { String warning((const char*)errorMsgs->GetBufferPointer(), errorMsgs->GetBufferSize()); PrintLine("WARNING: " + warning); } for(int i = 0; i < parseData->symbol_count; i++) { MOJOSHADER_symbol const& symbol = parseData->symbols[i]; String name(symbol.name); unsigned const reg = symbol.register_index; unsigned const regCount = symbol.register_count; // Check if the parameter is a constant or a texture sampler bool const isSampler = (name[0] == 's'); name = name.Substring(1); if (isSampler) { // Skip if it's a G-buffer sampler, which are aliases for the standard texture units if (name != "AlbedoBuffer" && name != "NormalBuffer" && name != "DepthBuffer" && name != "LightBuffer") { Parameter newTextureUnit(name, reg, 1); variation->textureUnits_.Push(newTextureUnit); } } else { Parameter newParam(name, reg, regCount); variation->constants_.Push(newParam); } } MOJOSHADER_freeParseData(parseData); // Create the last part of the output path (SM2/SM3) if it does not exist String outPath = GetPath(variation->outFileName_); if (!fileSystem_->DirExists(outPath)) fileSystem_->CreateDir(outPath); File outFile(context_); if (!outFile.Open(variation->outFileName_, FILE_WRITE)) { variation->errorMsg_ = "Could not open output file " + variation->outFileName_; compileFailed_ = true; } else { outFile.WriteFileID("USHD"); outFile.WriteShort((unsigned short)variation->type_); outFile.WriteShort(useSM3_ ? 3 : 2); outFile.WriteUInt(variation->constants_.Size()); for (unsigned i = 0; i < variation->constants_.Size(); ++i) { outFile.WriteString(variation->constants_[i].name_); outFile.WriteUByte(variation->constants_[i].register_); outFile.WriteUByte(variation->constants_[i].regCount_); } outFile.WriteUInt(variation->textureUnits_.Size()); for (unsigned i = 0; i < variation->textureUnits_.Size(); ++i) { outFile.WriteString(variation->textureUnits_[i].name_); outFile.WriteUByte(variation->textureUnits_[i].register_); } unsigned dataSize = variation->byteCode_.Size(); outFile.WriteUInt(dataSize); if (dataSize) outFile.Write(&variation->byteCode_[0], dataSize); } } if (shaderCode) shaderCode->Release(); if (errorMsgs) errorMsgs->Release(); }
void TileMapLayer2D::DrawDebugGeometry(DebugRenderer* debug, bool depthTest) { if (!debug) return; if (objectGroup_) { const Matrix3x4 transform = GetTileMap()->GetNode()->GetTransform(); for (unsigned i = 0; i < objectGroup_->GetNumObjects(); ++i) { TileMapObject2D* object = objectGroup_->GetObject(i); const Color& color = Color::YELLOW; const Vector2& size = object->GetSize(); const TileMapInfo2D& info = tileMap_->GetInfo(); switch (object->GetObjectType()) { case OT_RECTANGLE: { Vector<Vector2> points; switch (info.orientation_) { case O_ORTHOGONAL: case O_HEXAGONAL: case O_STAGGERED: { points.Push(Vector2::ZERO); points.Push(Vector2(size.x_, 0.0f)); points.Push(Vector2(size.x_, -size.y_)); points.Push(Vector2(0.0f, -size.y_)); break; } case O_ISOMETRIC: { float ratio = (info.tileWidth_ / info.tileHeight_) * 0.5f; points.Push(Vector2::ZERO); points.Push(Vector2(size.y_ * ratio, size.y_ * 0.5f)); points.Push(Vector2((size.x_ + size.y_) * ratio, (-size.x_ + size.y_) * 0.5f)); points.Push(Vector2(size.x_ * ratio, -size.x_ * 0.5f)); break; } } for (unsigned j = 0; j < points.Size(); ++j) debug->AddLine(Vector3(TransformNode2D(transform, points[j] + object->GetPosition())), Vector3(TransformNode2D(transform, points[(j + 1) % points.Size()] + object->GetPosition())), color, depthTest); } break; case OT_ELLIPSE: { const Vector2 halfSize = object->GetSize() * 0.5f; float ratio = (info.tileWidth_ / info.tileHeight_) * 0.5f; // For isometric only Vector2 pivot = object->GetPosition(); if (info.orientation_ == O_ISOMETRIC) { pivot += Vector2((halfSize.x_ + halfSize.y_) * ratio, (-halfSize.x_ + halfSize.y_) * 0.5f); } else { pivot += halfSize; } for (unsigned i = 0; i < 360; i += 30) { unsigned j = i + 30; float x1 = halfSize.x_ * Cos((float)i); float y1 = halfSize.y_ * Sin((float)i); float x2 = halfSize.x_ * Cos((float)j); float y2 = halfSize.y_ * Sin((float)j); Vector2 point1 = Vector2(x1, - y1); Vector2 point2 = Vector2(x2, - y2); if (info.orientation_ == O_ISOMETRIC) { point1 = Vector2((point1.x_ + point1.y_) * ratio, (point1.y_ - point1.x_) * 0.5f); point2 = Vector2((point2.x_ + point2.y_) * ratio, (point2.y_ - point2.x_) * 0.5f); } debug->AddLine(Vector3(TransformNode2D(transform, pivot + point1)), Vector3(TransformNode2D(transform, pivot + point2)), color, depthTest); } } break; case OT_POLYGON: case OT_POLYLINE: { for (unsigned j = 0; j < object->GetNumPoints() - 1; ++j) debug->AddLine(Vector3(TransformNode2D(transform, object->GetPoint(j))), Vector3(TransformNode2D(transform, object->GetPoint(j + 1))), color, depthTest); if (object->GetObjectType() == OT_POLYGON) debug->AddLine(Vector3(TransformNode2D(transform, object->GetPoint(0))), Vector3(TransformNode2D(transform, object->GetPoint(object->GetNumPoints() - 1))), color, depthTest); // Also draw a circle at origin to indicate direction else debug->AddCircle(Vector3(TransformNode2D(transform, object->GetPoint(0))), Vector3::FORWARD, 0.05f, color, 64, depthTest); } break; default: break; } } } }
/* assemble the force vector B (A*X = B). */ int SymSparseLinSOE::addB(const Vector &in_v, const ID &in_id, double fact) { // check for a quick return if (fact == 0.0) return 0; int idSize = in_id.Size(); // check that m and id are of similar size if (idSize != in_v.Size() ) { opserr << "SymSparseLinSOE::addB() "; opserr << " - Vector and ID not of similar sizes\n"; return -1; } // construct v and id based on non-negative id values. int newPt = 0; int *id = new (nothrow) int[idSize]; double *v = new (nothrow) double[idSize]; for (int ii = 0; ii < idSize; ii++) { if (in_id(ii) >= 0 && in_id(ii) < size) { id[newPt] = in_id(ii); v[newPt] = in_v(ii); newPt++; } } idSize = newPt; if (idSize == 0) { delete [] id; delete [] v; return 0; } int *newID = new (nothrow) int[idSize]; if (newID == 0) { opserr << "WARNING SymSparseLinSOE::SymSparseLinSOE :"; opserr << " ran out of memory for vectors (newID)"; return -1; } for (int i=0; i<idSize; i++) { newID[i] = id[i]; if (newID[i] >= 0) newID[i] = invp[newID[i]]; } if (fact == 1.0) { // do not need to multiply if fact == 1.0 for (int i=0; i<idSize; i++) { int pos = newID[i]; if (pos <size && pos >= 0) B[pos] += v[i]; } } else if (fact == -1.0) { // do not need to multiply if fact == -1.0 for (int i=0; i<idSize; i++) { int pos = newID[i]; if (pos <size && pos >= 0) B[pos] -= v[i]; } } else { for (int i=0; i<idSize; i++) { int pos = newID[i]; if (pos <size && pos >= 0) B[pos] += v[i] * fact; // assemble } } delete [] newID; delete [] v; delete [] id; return 0; }
bool CEJavascript::CheckJSErrors(bool fullCheck) { errors_.Clear(); Editor* editor = GetSubsystem<Editor>(); Project* project = editor->GetProject(); FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (!project) { modifiedJS_.Clear(); return true; } Vector<String>& filesToCheck = modifiedJS_; Vector<String> allFiles; if (fullCheck) { filesToCheck = allFiles; String componentsPath = AddTrailingSlash(project->GetComponentsPath()); String scriptsPath = AddTrailingSlash(project->GetScriptsPath()); String modulesPath = AddTrailingSlash(project->GetModulesPath()); Vector<String> files; fileSystem->ScanDir(files, componentsPath, "*.js", SCAN_FILES, true ); for (unsigned i = 0; i < files.Size(); i++) allFiles.Push(componentsPath + files[i]); fileSystem->ScanDir(files, scriptsPath, "*.js", SCAN_FILES, true ); for (unsigned i = 0; i < files.Size(); i++) allFiles.Push(scriptsPath + files[i]); fileSystem->ScanDir(files, modulesPath, "*.js", SCAN_FILES, true ); for (unsigned i = 0; i < files.Size(); i++) allFiles.Push(modulesPath + files[i]); } bool ok = true; for (unsigned j = 0; j < filesToCheck.Size(); j++) { String source; String fullpath = filesToCheck[j]; ReadZeroTerminatedSourceFile(fullpath, source); duk_get_global_string(ctx_, "__clockwork_parse_error_check"); duk_push_string(ctx_, source.CString()); if (duk_pcall(ctx_, 1)) { printf("Error: %s\n", duk_safe_to_string(ctx_, -1)); } else { if (duk_is_boolean(ctx_, -1)) { // error if (duk_to_boolean(ctx_, -1)) ok = false; } else if (duk_is_object(ctx_, -1)) { ok = false; JSError error; error.fullpath = fullpath; duk_get_prop_string(ctx_, -1, "message"); error.message = duk_to_string(ctx_, -1); duk_pop(ctx_); duk_get_prop_string(ctx_, -1, "loc"); duk_get_prop_string(ctx_, -1, "line"); error.line = duk_to_number(ctx_, -1); duk_get_prop_string(ctx_, -2, "column"); error.column = duk_to_number(ctx_, -1); duk_get_prop_string(ctx_, -4, "raisedAt"); error.tokenPos = duk_to_number(ctx_, -1); duk_pop_3(ctx_); errors_.Push(error); } else { // what to do? } } // ignore result duk_pop(ctx_); } modifiedJS_.Clear(); return !ok; }
double BFGS ( Vector & x, // i: Startwert // o: Loesung, falls IFAIL = 0 const MinFunction & fun, const OptiParameters & par, double eps ) { int n = x.Size(); long it; char a1crit, a3acrit; Vector d(n), g(n), p(n), temp(n), bs(n), xneu(n), y(n), s(n), x0(n); DenseMatrix l(n); DenseMatrix hesse(n); double /* normg, */ alphahat, hd, fold; double a1, a2; const double mu1 = 0.1, sigma = 0.1, xi1 = 1, xi2 = 10; const double tau = 0.1, tau1 = 0.1, tau2 = 0.6; Vector typx(x.Size()); // i: typische Groessenordnung der Komponenten double f, f0; double typf; // i: typische Groessenordnung der Loesung double fmin = -1e5; // i: untere Schranke fuer Funktionswert // double eps = 1e-8; // i: Abbruchschranke fuer relativen Gradienten double tauf = 0.1; // i: Abbruchschranke fuer die relative Aenderung der // Funktionswerte int ifail; // o: 0 .. Erfolg // -1 .. Unterschreitung von fmin // 1 .. kein Erfolg bei Liniensuche // 2 .. Überschreitung von itmax typx = par.typx; typf = par.typf; l = 0; for (int i = 1; i <= n; i++) l.Elem(i, i) = 1; f = fun.FuncGrad (x, g); f0 = f; x0 = x; it = 0; do { // Restart if (it % (5 * n) == 0) { for (int i = 1; i <= n; i++) d(i-1) = typf/ sqr (typx(i-1)); // 1; for (int i = 2; i <= n; i++) for (int j = 1; j < i; j++) l.Elem(i, j) = 0; /* hesse = 0; for (i = 1; i <= n; i++) hesse.Elem(i, i) = typf / sqr (typx.Get(i)); fun.ApproximateHesse (x, hesse); Cholesky (hesse, l, d); */ } it++; if (it > par.maxit_bfgs) { ifail = 2; break; } // Solve with factorized B SolveLDLt (l, d, g, p); // (*testout) << "l " << l << endl // << "d " << d << endl // << "g " << g << endl // << "p " << p << endl; p *= -1; y = g; fold = f; // line search alphahat = 1; lines (x, xneu, p, f, g, fun, par, alphahat, fmin, mu1, sigma, xi1, xi2, tau, tau1, tau2, ifail); if(ifail == 1) (*testout) << "no success with linesearch" << endl; /* // if (it > par.maxit_bfgs/2) { (*testout) << "x = " << x << endl; (*testout) << "xneu = " << xneu << endl; (*testout) << "f = " << f << endl; (*testout) << "g = " << g << endl; } */ // (*testout) << "it = " << it << " f = " << f << endl; // if (ifail != 0) break; s.Set2 (1, xneu, -1, x); y *= -1; y.Add (1,g); // y += g; x = xneu; // BFGS Update MultLDLt (l, d, s, bs); a1 = y * s; a2 = s * bs; if (a1 > 0 && a2 > 0) { if (LDLtUpdate (l, d, 1 / a1, y) != 0) { cerr << "BFGS update error1" << endl; (*testout) << "BFGS update error1" << endl; (*testout) << "l " << endl << l << endl << "d " << d << endl; ifail = 1; break; } if (LDLtUpdate (l, d, -1 / a2, bs) != 0) { cerr << "BFGS update error2" << endl; (*testout) << "BFGS update error2" << endl; (*testout) << "l " << endl << l << endl << "d " << d << endl; ifail = 1; break; } } // Calculate stop conditions hd = eps * max2 (typf, fabs (f)); a1crit = 1; for (int i = 1; i <= n; i++) if ( fabs (g(i-1)) * max2 (typx(i-1), fabs (x(i-1))) > hd) a1crit = 0; a3acrit = (fold - f <= tauf * max2 (typf, fabs (f))); // testout << "g = " << g << endl; // testout << "a1crit, a3crit = " << int(a1crit) << ", " << int(a3acrit) << endl; /* // Output for tests normg = sqrt (g * g); testout << "it =" << setw (5) << it << " f =" << setw (12) << setprecision (5) << f << " |g| =" << setw (12) << setprecision (5) << normg; testout << " x = (" << setw (12) << setprecision (5) << x.Elem(1); for (i = 2; i <= n; i++) testout << "," << setw (12) << setprecision (5) << x.Elem(i); testout << ")" << endl; */ //(*testout) << "it = " << it << " f = " << f << " x = " << x << endl // << " g = " << g << " p = " << p << endl << endl; // (*testout) << "|g| = " << g.L2Norm() << endl; if (g.L2Norm() < fun.GradStopping (x)) break; } while (!a1crit || !a3acrit); /* (*testout) << "it = " << it << " g = " << g << " f = " << f << " fail = " << ifail << endl; */ if (f0 < f || (ifail == 1)) { (*testout) << "fail, f = " << f << " f0 = " << f0 << endl; f = f0; x = x0; } // (*testout) << "x = " << x << ", x0 = " << x0 << endl; return f; }
bool ScriptFile::AddScriptSection(asIScriptEngine* engine, Deserializer& source) { ResourceCache* cache = GetSubsystem<ResourceCache>(); unsigned dataSize = source.GetSize(); SharedArrayPtr<char> buffer(new char[dataSize]); source.Read((void*)buffer.Get(), dataSize); // Pre-parse for includes // Adapted from Angelscript's scriptbuilder add-on Vector<String> includeFiles; unsigned pos = 0; while (pos < dataSize) { unsigned len; asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_COMMENT || t == asTC_WHITESPACE) { pos += len; continue; } // Is this a preprocessor directive? if (buffer[pos] == '#') { int start = pos++; asETokenClass t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_IDENTIFIER) { String token(&buffer[pos], (unsigned)len); if (token == "include") { pos += len; t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); if (t == asTC_WHITESPACE) { pos += len; t = engine->ParseToken(&buffer[pos], dataSize - pos, &len); } if (t == asTC_VALUE && len > 2 && buffer[pos] == '"') { // Get the include file String includeFile(&buffer[pos + 1], (unsigned)(len - 2)); pos += len; // If the file is not found as it is, add the path of current file but only if it is found there if (!cache->Exists(includeFile)) { String prefixedIncludeFile = GetPath(GetName()) + includeFile; if (cache->Exists(prefixedIncludeFile)) includeFile = prefixedIncludeFile; } String includeFileLower = includeFile.ToLower(); // If not included yet, store it for later processing if (!includeFiles_.Contains(includeFileLower)) { includeFiles_.Insert(includeFileLower); includeFiles.Push(includeFile); } // Overwrite the include directive with space characters to avoid compiler error memset(&buffer[start], ' ', pos - start); } } } } // Don't search includes within statement blocks or between tokens in statements else { unsigned len; // Skip until ; or { whichever comes first while (pos < dataSize && buffer[pos] != ';' && buffer[pos] != '{') { engine->ParseToken(&buffer[pos], 0, &len); pos += len; } // Skip entire statement block if (pos < dataSize && buffer[pos] == '{') { ++pos; // Find the end of the statement block int level = 1; while (level > 0 && pos < dataSize) { asETokenClass t = engine->ParseToken(&buffer[pos], 0, &len); if (t == asTC_KEYWORD) { if (buffer[pos] == '{') ++level; else if (buffer[pos] == '}') --level; } pos += len; } } else ++pos; } } // Process includes first for (unsigned i = 0; i < includeFiles.Size(); ++i) { cache->StoreResourceDependency(this, includeFiles[i]); SharedPtr<File> file = cache->GetFile(includeFiles[i]); if (file) { if (!AddScriptSection(engine, *file)) return false; } else { URHO3D_LOGERROR("Could not process all the include directives in " + GetName() + ": missing " + includeFiles[i]); return false; } } // Then add this section if (scriptModule_->AddScriptSection(source.GetName().CString(), (const char*)buffer.Get(), dataSize) < 0) { URHO3D_LOGERROR("Failed to add script section " + source.GetName()); return false; } SetMemoryUse(GetMemoryUse() + dataSize); return true; }
void InferSummaries(const Vector<BlockSummary*> &summary_list) { static BaseTimer infer_timer("infer_summaries"); Timer _timer(&infer_timer); if (summary_list.Empty()) return; Variable *function = summary_list[0]->GetId()->BaseVar(); Vector<BlockCFG*> *annot_list = BodyAnnotCache.Lookup(function->GetName()); // all traces which might refer to the result of pointer arithmetic. Vector<Exp*> arithmetic_list; ArithmeticEscape escape(function, arithmetic_list); // initial pass over the CFGs to get traces used in pointer arithmetic. for (size_t ind = 0; ind < summary_list.Size(); ind++) { BlockSummary *sum = summary_list[ind]; BlockCFG *cfg = sum->GetMemory()->GetCFG(); for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) { PEdge *edge = cfg->GetEdge(eind); if (PEdgeAssign *assign_edge = edge->IfAssign()) { Exp *left = assign_edge->GetLeftSide(); Exp *right = assign_edge->GetRightSide(); ProcessArithmeticAssign(&escape, cfg->GetId(), left, right); } } } for (size_t ind = 0; ind < summary_list.Size(); ind++) { BlockSummary *sum = summary_list[ind]; BlockMemory *mcfg = sum->GetMemory(); BlockCFG *cfg = mcfg->GetCFG(); // accumulate all the assertions at points in the CFG. Vector<AssertInfo> asserts; // add assertions at function exit for any postconditions. if (cfg->GetId()->Kind() == B_Function) { for (size_t aind = 0; annot_list && aind < annot_list->Size(); aind++) { BlockCFG *annot_cfg = annot_list->At(aind); if (annot_cfg->GetAnnotationKind() != AK_Postcondition) continue; if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) { AssertInfo info; info.kind = ASK_Annotation; info.cls = ASC_Check; info.point = cfg->GetExitPoint(); info.bit = bit; asserts.PushBack(info); } } } // add assertions for any point annotations within the CFG. for (size_t pind = 0; pind < cfg->GetPointAnnotationCount(); pind++) { PointAnnotation pann = cfg->GetPointAnnotation(pind); BlockCFG *annot_cfg = GetAnnotationCFG(pann.annot); if (!annot_cfg) continue; if (annot_cfg->GetAnnotationKind() != AK_Assert) continue; if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) { AssertInfo info; info.kind = ASK_Annotation; info.cls = ASC_Check; info.point = pann.point; info.bit = bit; asserts.PushBack(info); } } for (size_t eind = 0; eind < cfg->GetEdgeCount(); eind++) { PEdge *edge = cfg->GetEdge(eind); PPoint point = edge->GetSource(); if (PEdgeAnnotation *nedge = edge->IfAnnotation()) { // add an assertion for this annotation if it not an assume. BlockCFG *annot_cfg = GetAnnotationCFG(nedge->GetAnnotationId()); if (!annot_cfg) continue; if (annot_cfg->GetAnnotationKind() != AK_Assert && annot_cfg->GetAnnotationKind() != AK_AssertRuntime) { continue; } if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) { AssertInfo info; info.kind = (annot_cfg->GetAnnotationKind() == AK_Assert) ? ASK_Annotation : ASK_AnnotationRuntime; info.cls = ASC_Check; info.point = point; info.bit = bit; asserts.PushBack(info); } } // add assertions for any invariants affected by a write. Exp *left = NULL; if (PEdgeAssign *nedge = edge->IfAssign()) left = nedge->GetLeftSide(); if (PEdgeCall *nedge = edge->IfCall()) left = nedge->GetReturnValue(); // for now our detection of affected invariants is pretty crude; // writes to fields can affect type invariants on the field's type // which use that field, and writes to global variables can affect // invariants on that global. TODO: pin this down once we draw a // precise line between which invariants can and can't be checked. if (left && left->IsFld()) { ExpFld *nleft = left->AsFld(); String *csu_name = nleft->GetField()->GetCSUType()->GetCSUName(); Vector<BlockCFG*> *comp_annot_list = CompAnnotCache.Lookup(csu_name); for (size_t aind = 0; comp_annot_list && aind < comp_annot_list->Size(); aind++) { BlockCFG *annot_cfg = comp_annot_list->At(aind); if (annot_cfg->GetAnnotationKind() != AK_Invariant) continue; Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg); if (!bit) continue; Vector<Exp*> lval_list; LvalListVisitor visitor(&lval_list); bit->DoVisit(&visitor); bool uses_field = false; for (size_t ind = 0; ind < lval_list.Size(); ind++) { if (ExpFld *lval = lval_list[ind]->IfFld()) { if (lval->GetField() == nleft->GetField()) uses_field = true; } } if (uses_field) { // this is a type invariant which uses the field being written // as an lvalue. we need to assert this write preserves // the invariant. BlockId *id = annot_cfg->GetId(); Variable *this_var = Variable::Make(id, VK_This, NULL, 0, NULL); Exp *this_exp = Exp::MakeVar(this_var); Exp *this_drf = Exp::MakeDrf(this_exp); Bit *new_bit = BitReplaceExp(bit, this_drf, nleft->GetTarget()); AssertInfo info; info.kind = ASK_Invariant; info.cls = ASC_Check; info.point = point; info.bit = new_bit; asserts.PushBack(info); } } CompAnnotCache.Release(csu_name); } if (left && left->IsVar()) { Variable *var = left->AsVar()->GetVariable(); if (var->Kind() == VK_Glob) { Vector<BlockCFG*> *glob_annot_list = InitAnnotCache.Lookup(var->GetName()); for (size_t aind = 0; glob_annot_list && aind < glob_annot_list->Size(); aind++) { BlockCFG *annot_cfg = glob_annot_list->At(aind); Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg); if (!bit) continue; AssertInfo info; info.kind = ASK_Invariant; info.cls = ASC_Check; info.point = point; info.bit = bit; asserts.PushBack(info); } InitAnnotCache.Release(var->GetName()); } } if (PEdgeCall *nedge = edge->IfCall()) { // add assertions for any callee preconditions. // pull preconditions from both direct and indirect calls. Vector<Variable*> callee_names; if (Variable *callee = nedge->GetDirectFunction()) { callee_names.PushBack(callee); } else { CallEdgeSet *callees = CalleeCache.Lookup(function); if (callees) { for (size_t cind = 0; cind < callees->GetEdgeCount(); cind++) { const CallEdge &edge = callees->GetEdge(cind); if (edge.where.id == cfg->GetId() && edge.where.point == point) callee_names.PushBack(edge.callee); } } // CalleeCache release is below. } for (size_t cind = 0; cind < callee_names.Size(); cind++) { String *callee = callee_names[cind]->GetName(); Vector<BlockCFG*> *call_annot_list = BodyAnnotCache.Lookup(callee); for (size_t aind = 0; call_annot_list && aind < call_annot_list->Size(); aind++) { BlockCFG *annot_cfg = call_annot_list->At(aind); if (annot_cfg->GetAnnotationKind() != AK_Precondition) continue; if (Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg)) { ConvertCallsiteMapper mapper(cfg, point, false); Bit *caller_bit = bit->DoMap(&mapper); if (!caller_bit) continue; AssertInfo info; info.kind = ASK_Annotation; info.cls = ASC_Check; info.point = point; info.bit = caller_bit; asserts.PushBack(info); } } BodyAnnotCache.Release(callee); } if (!nedge->GetDirectFunction()) CalleeCache.Release(function); } BufferScanVisitor write_visitor(asserts, arithmetic_list, point, true); BufferScanVisitor read_visitor(asserts, arithmetic_list, point, false); IntegerScanVisitor integer_visitor(asserts, point); GCScanVisitor gcsafe_visitor(asserts, point); // only look at the written lvalues for the write visitor. if (PEdgeAssign *assign = edge->IfAssign()) write_visitor.Visit(assign->GetLeftSide()); if (PEdgeCall *call = edge->IfCall()) { if (Exp *returned = call->GetReturnValue()) write_visitor.Visit(returned); } edge->DoVisit(&read_visitor); // disable integer overflow visitor for now. // edge->DoVisit(&integer_visitor); edge->DoVisit(&gcsafe_visitor); } if (cfg->GetId()->Kind() == B_Function) { BlockModset *modset = GetBlockModset(cfg->GetId()); if (modset->CanGC()) { AssertInfo info; info.kind = ASK_CanGC; info.cls = ASC_Check; info.point = cfg->GetExitPoint(); String *name = cfg->GetId()->BaseVar()->GetName(); Variable *var = Variable::Make(NULL, VK_Glob, name, 0, name); Exp *varexp = Exp::MakeVar(var); Exp *gcsafe = Exp::MakeGCSafe(varexp, false); info.bit = Bit::MakeVar(gcsafe); asserts.PushBack(info); } } MarkRedundantAssertions(mcfg, asserts); // move the finished assertion list into the summary. for (size_t ind = 0; ind < asserts.Size(); ind++) { const AssertInfo &info = asserts[ind]; sum->AddAssert(info.kind, info.cls, info.point, info.bit); } } // infer delta and termination invariants for all summaries. for (size_t ind = 0; ind < summary_list.Size(); ind++) InferInvariants(summary_list[ind], arithmetic_list); BodyAnnotCache.Release(function->GetName()); }
bool ShaderVariation::Create() { Release(); if (!owner_) { compilerOutput_ = "Owner shader has expired"; return false; } object_ = glCreateShader(type_ == VS ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); if (!object_) { compilerOutput_ = "Could not create shader object"; return false; } const String& originalShaderCode = owner_->GetSourceCode(type_); String shaderCode; // Distinguish between VS and PS compile in case the shader code wants to include/omit different things shaderCode += type_ == VS ? "#define COMPILEVS\n" : "#define COMPILEPS\n"; // Prepend the defines to the shader code Vector<String> defineVec = defines_.Split(' '); for (unsigned i = 0; i < defineVec.Size(); ++i) { // Add extra space for the checking code below String defineString = "#define " + defineVec[i].Replaced('=', ' ') + " \n"; shaderCode += defineString; // In debug mode, check that all defines are referenced by the shader code #ifdef _DEBUG String defineCheck = defineString.Substring(8, defineString.Find(' ', 8) - 8); if (originalShaderCode.Find(defineCheck) == String::NPOS) LOGWARNING("Shader " + GetName() + " does not use the define " + defineCheck); #endif } #ifdef RASPI if (type_ == VS) shaderCode += "#define RASPI\n"; #endif shaderCode += originalShaderCode; const char* shaderCStr = shaderCode.CString(); glShaderSource(object_, 1, &shaderCStr, 0); glCompileShader(object_); int compiled, length; glGetShaderiv(object_, GL_COMPILE_STATUS, &compiled); compiled_ = compiled != 0; if (!compiled_) { glGetShaderiv(object_, GL_INFO_LOG_LENGTH, &length); compilerOutput_.Resize(length); int outLength; glGetShaderInfoLog(object_, length, &outLength, &compilerOutput_[0]); } else compilerOutput_.Clear(); return compiled_; }
void TopoSortCFG(BlockCFG *cfg) { // can't topo sort a CFG that might have loops. Assert(cfg->GetLoopHeadCount() == 0); // map from old CFG points to the new points in the topo order. we can only // add a new point once we've added all its predecessors. PPointListHash remapping; // points in the remappping, in the order to add them to the CFG. Vector<Location*> new_points; // map from new points back to original CFG points. Vector<PPoint> old_points; // worklist items are the points where the sources of incoming edges have // already been added to the remapping, the point itself has not. Vector<PPoint> worklist; PPoint entry_point = cfg->GetEntryPoint(); PPoint exit_point = cfg->GetExitPoint(); // seed the worklist. worklist.PushBack(entry_point); while (!worklist.Empty()) { // pick the point from the worklist with the minimum line number. // if there is code like: // if (x) // a; // else // b; // we could add either a or b to the remapping first, but we want to add // a first. the ordering of points is used for naming loops, and we want // this ordering to be deterministic and map back to the code predictably. size_t best_index = 0; size_t best_line = cfg->GetPointLocation(worklist[0])->Line(); for (size_t ind = 1; ind < worklist.Size(); ind++) { size_t new_line = cfg->GetPointLocation(worklist[ind])->Line(); if (new_line < best_line) { best_index = ind; best_line = new_line; } } PPoint point = worklist[best_index]; worklist[best_index] = worklist.Back(); worklist.PopBack(); Assert(!remapping.Lookup(point, false)); Location *loc = cfg->GetPointLocation(point); loc->IncRef(); new_points.PushBack(loc); old_points.PushBack(point); remapping.Insert(point, new_points.Size()); const Vector<PEdge*> &outgoing = cfg->GetOutgoingEdges(point); for (size_t oind = 0; oind < outgoing.Size(); oind++) { PEdge *edge = outgoing[oind]; PPoint target = edge->GetTarget(); // this can happen if there are multiple edges from the worklist point // to the target, e.g. 'if (x) {}'. not going to happen much. if (worklist.Contains(target)) continue; Assert(!remapping.Lookup(target, false)); // we can add the target to the worklist if it has no incoming edges // from points not in the remapping. bool missing_incoming = false; const Vector<PEdge*> &incoming = cfg->GetIncomingEdges(target); for (size_t iind = 0; iind < incoming.Size(); iind++) { PEdge *edge = incoming[iind]; PPoint source = edge->GetSource(); if (!remapping.Lookup(source, false)) { missing_incoming = true; break; } } if (!missing_incoming) worklist.PushBack(target); } } // this assert will fail if either the CFG contains cycles, or if there are // nodes unreachable from the start. neither of these cases should be // possible here. Assert(new_points.Size() == cfg->GetPointCount()); Assert(old_points.Size() == cfg->GetPointCount()); // remap all the edges. this is also done so that the edges will be // in topological order according to their source points. Vector<PEdge*> new_edges; for (size_t pind = 0; pind < old_points.Size(); pind++) { const Vector<PEdge*> &edges = cfg->GetOutgoingEdges(old_points[pind]); for (size_t eind = 0; eind < edges.Size(); eind++) { PEdge *edge = edges[eind]; PPoint new_source = remapping.LookupSingle(edge->GetSource()); PPoint new_target = remapping.LookupSingle(edge->GetTarget()); PEdge *new_edge = PEdge::ChangeEdge(edge, new_source, new_target); new_edges.PushBack(new_edge); } } // clear out the initial CFG. cfg->ClearBody(); // add the new points, edges, annotations. for (size_t pind = 0; pind < new_points.Size(); pind++) cfg->AddPoint(new_points[pind]); for (size_t eind = 0; eind < new_edges.Size(); eind++) cfg->AddEdge(new_edges[eind]); // set the new entry point. this had better be the first point in the order. PPoint new_entry_point = remapping.LookupSingle(entry_point); Assert(new_entry_point == 1); cfg->SetEntryPoint(new_entry_point); if (exit_point) { // set the new exit point. this had better be the last point in the order. PPoint new_exit_point = remapping.LookupSingle(exit_point); Assert(new_exit_point == new_points.Size()); cfg->SetExitPoint(new_exit_point); } }
void JSBHaxe::ExportModuleClasses(JSBModule* module) { Vector<SharedPtr<JSBClass>> classes = module->GetClasses(); if (!classes.Size()) return; source_ += "\n"; for (unsigned i = 0; i < classes.Size(); i++) { JSBClass* klass = classes.At(i); if (klass->IsNumberArray()) { source_ += "typedef " + klass->GetName() + " = Array<Float>;\n"; continue; } source_ += "@:native(\"Atomic." + klass->GetName() + "\")\n"; source_ += "extern class " + klass->GetName(); JSBClass* base = klass->GetBaseClass(); if (base) { source_ += " extends " + base->GetName(); } source_ += " {\n\n"; Vector<String> propertyNames; klass->GetPropertyNames(propertyNames); for (unsigned j = 0; j < propertyNames.Size(); j++) { JSBProperty* prop = klass->GetProperty(propertyNames[j]); JSBFunctionType* ftype = NULL; if (prop->getter_ && !prop->getter_->Skip()) { ftype = prop->getter_->GetReturnType(); } else if (prop->setter_ && !prop->setter_->Skip()) ftype = prop->setter_->GetParameters()[0]; if (!ftype) continue; String scriptType = GetScriptType(ftype); String scriptName = prop->GetCasePropertyName(); if (!checkV(klass, scriptName, scriptType)) { //rename haxe reserved words if (scriptName == "override") { scriptName = "overide"; } if (scriptName == "dynamic") { scriptName = "dynamik"; } source_ += " var " + scriptName + ": " + scriptType + ";\n"; } } if (propertyNames.Size()) source_ += "\n"; JSBFunction* constructor = klass->GetConstructor(); if (constructor) { ExportFunction(constructor); source_ += "\n"; } PODVector<JSBFunction*>& functions = klass->GetFunctions(); for (unsigned j = 0; j < functions.Size(); j++) { JSBFunction* func = functions[j]; if (func->IsConstructor() || func->IsDestructor() || func->Skip()) continue; ExportFunction(func); } for (unsigned j = 0; j < klass->GetNumHaxeDecl(); j++) { source_ += " " + klass->GetHaxeDecl(j) + "\n"; } source_ += "\n}\n\n"; } source_ += "\n"; }
void AtomicTool::Start() { // Subscribe to events SubscribeToEvent(E_COMMANDERROR, HANDLER(AtomicTool, HandleCommandError)); SubscribeToEvent(E_COMMANDFINISHED, HANDLER(AtomicTool, HandleCommandFinished)); SubscribeToEvent(E_LICENSE_EULAREQUIRED, HANDLER(AtomicTool, HandleLicenseEulaRequired)); SubscribeToEvent(E_LICENSE_ACTIVATIONREQUIRED, HANDLER(AtomicTool, HandleLicenseActivationRequired)); SubscribeToEvent(E_LICENSE_ERROR, HANDLER(AtomicTool, HandleLicenseError)); SubscribeToEvent(E_LICENSE_SUCCESS, HANDLER(AtomicTool, HandleLicenseSuccess)); const Vector<String>& arguments = GetArguments(); ToolSystem* tsystem = new ToolSystem(context_); context_->RegisterSubsystem(tsystem); ToolEnvironment* env = new ToolEnvironment(context_); context_->RegisterSubsystem(env); //#ifdef ATOMIC_DEV_BUILD if (!env->InitFromJSON()) { ErrorExit(ToString("Unable to initialize tool environment from %s", env->GetDevConfigFilename().CString())); return; } if (!cliDataPath_.Length()) { cliDataPath_ = env->GetRootSourceDir() + "/Resources/"; } //#endif tsystem->SetCLI(); tsystem->SetDataPath(cliDataPath_); if (activationKey_.Length()) { DoActivation(); return; } else if (deactivate_) { DoDeactivation(); return; } BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); SharedPtr<CommandParser> parser(new CommandParser(context_)); SharedPtr<Command> cmd(parser->Parse(arguments)); if (!cmd) { String error = "No command found"; if (parser->GetErrorMessage().Length()) error = parser->GetErrorMessage(); ErrorExit(error); return; } if (cmd->RequiresProjectLoad()) { FileSystem* fileSystem = GetSubsystem<FileSystem>(); String projectDirectory = fileSystem->GetCurrentDir(); Vector<String> projectFiles; fileSystem->ScanDir(projectFiles, projectDirectory, "*.atomic", SCAN_FILES, false); if (!projectFiles.Size()) { ErrorExit(ToString("No .atomic project file in %s", projectDirectory.CString())); return; } else if (projectFiles.Size() > 1) { ErrorExit(ToString("Multiple .atomic project files found in %s", projectDirectory.CString())); return; } String projectFile = projectDirectory + "/" + projectFiles[0]; if (!tsystem->LoadProject(projectFile)) { //ErrorExit(ToString("Failed to load project: %s", projectFile.CString())); //return; } // Set the build path String buildFolder = projectDirectory + "/" + "Build"; buildSystem->SetBuildPath(buildFolder); if (!fileSystem->DirExists(buildFolder)) { fileSystem->CreateDir(buildFolder); if (!fileSystem->DirExists(buildFolder)) { ErrorExit(ToString("Failed to create build folder: %s", buildFolder.CString())); return; } } } command_ = cmd; // BEGIN LICENSE MANAGEMENT if (cmd->RequiresLicenseValidation()) { GetSubsystem<LicenseSystem>()->Initialize(); } else { if (command_.Null()) { GetSubsystem<Engine>()->Exit(); return; } command_->Run(); } // END LICENSE MANAGEMENT }
void Run(const Vector<String>& arguments) { if (arguments.Size() < 1) { ErrorExit( "Usage: ShaderCompiler <definitionfile> [outputpath] [options]\n\n" "Options:\n" "-t<VS|PS> Compile only vertex or pixel shaders, by default compile both\n" "-v<name> Compile only the shader variation with name\n" "-d<define> Add a define. Add SM3 to compile for Shader Model 3\n\n" "If output path is not specified, shader binaries will be output into the same\n" "directory as the definition file. Specify a wildcard to compile multiple\n" "shaders." ); } String path, file, extension; SplitPath(arguments[0], path, file, extension); inDir_ = AddTrailingSlash(path); if (arguments.Size() > 1 && arguments[1][0] != '-') outDir_ = AddTrailingSlash(arguments[1]); else outDir_ = inDir_; for (unsigned i = 1; i < arguments.Size(); ++i) { if (arguments[i][0] == '-' && arguments[i].Length() > 1) { char option = arguments[i][1]; String arg = arguments[i].Substring(2); switch (option) { case 'd': { Vector<String> nameAndValue = arg.Split('='); if (nameAndValue.Size() == 2) { defines_.Push(nameAndValue[0]); defineValues_.Push(nameAndValue[1]); if (nameAndValue[0] == "SM3" && ToInt(nameAndValue[1]) > 0) useSM3_ = true; } else { defines_.Push(arg); defineValues_.Push("1"); if (arg == "SM3") useSM3_ = true; } } break; case 't': if (arg.ToLower() == "vs") { compileVS_ = true; compilePS_ = false; } else if (arg.ToLower() == "ps") { compileVS_ = false; compilePS_ = true; } break; case 'v': compileVariation_ = true; variationName_ = arg; break; } } } if (!file.StartsWith("*")) CompileShader(arguments[0]); else { Vector<String> shaderFiles; fileSystem_->ScanDir(shaderFiles, inDir_, file + extension, SCAN_FILES, false); for (unsigned i = 0; i < shaderFiles.Size(); ++i) CompileShader(inDir_ + shaderFiles[i]); } }
void Variant::FromString(VariantType type, const char* value) { switch (type) { case VAR_INT: *this = ToInt(value); break; case VAR_BOOL: *this = ToBool(value); break; case VAR_FLOAT: *this = ToFloat(value); break; case VAR_VECTOR2: *this = ToVector2(value); break; case VAR_VECTOR3: *this = ToVector3(value); break; case VAR_VECTOR4: *this = ToVector4(value); break; case VAR_QUATERNION: *this = ToQuaternion(value); break; case VAR_COLOR: *this = ToColor(value); break; case VAR_STRING: *this = value; break; case VAR_BUFFER: { SetType(VAR_BUFFER); PODVector<unsigned char>& buffer = *(reinterpret_cast<PODVector<unsigned char>*>(&value_)); StringToBuffer(buffer, value); } break; case VAR_PTR: *this = (void*)0; break; case VAR_RESOURCEREF: { Vector<String> values = String::Split(value, ';'); if (values.Size() == 2) { SetType(VAR_RESOURCEREF); ResourceRef& ref = *(reinterpret_cast<ResourceRef*>(&value_)); ref.type_ = values[0]; ref.name_ = values[1]; } } break; case VAR_RESOURCEREFLIST: { Vector<String> values = String::Split(value, ';'); if (values.Size() >= 1) { SetType(VAR_RESOURCEREFLIST); ResourceRefList& refList = *(reinterpret_cast<ResourceRefList*>(&value_)); refList.type_ = values[0]; refList.names_.Resize(values.Size() - 1); for (unsigned i = 1; i < values.Size(); ++i) refList.names_[i - 1] = values[i]; } } break; case VAR_INTRECT: *this = ToIntRect(value); break; case VAR_INTVECTOR2: *this = ToIntVector2(value); break; default: SetType(VAR_NONE); } }
void CompileShader(const String& fileName) { String file = GetFileName(fileName); XMLFile doc(context_); File source(context_); source.Open(fileName); if (!doc.Load(source)) ErrorExit("Could not open input file " + fileName); XMLElement shaders = doc.GetRoot("shaders"); if (!shaders) ErrorExit("No shaders element in " + source.GetName()); if (compileVS_) { ShaderParser vsParser; if (!vsParser.Parse(VS, shaders, defines_, defineValues_)) ErrorExit("VS: " + vsParser.GetErrorMessage()); const HashMap<String, unsigned>& combinations = vsParser.GetAllCombinations(); for (HashMap<String, unsigned>::ConstIterator i = combinations.Begin(); i != combinations.End(); ++i) { if (!compileVariation_ || i->first_ == variationName_) { ShaderCombination src = vsParser.GetCombination(i->first_); CompiledVariation compile; compile.type_ = VS; compile.name_ = file; compile.outFileName_ = outDir_ + file; if (!src.name_.Empty()) { compile.name_ += "_" + src.name_; compile.outFileName_ += "_" + src.name_; } compile.outFileName_ += useSM3_ ? ".vs3" : ".vs2"; compile.defines_ = src.defines_; compile.defineValues_ = src.defineValues_; variations_.Push(compile); workList_.Push(&variations_.Back()); } } } if (compilePS_) { ShaderParser psParser; if (!psParser.Parse(PS, shaders, defines_, defineValues_)) ErrorExit("PS: " + psParser.GetErrorMessage()); const HashMap<String, unsigned>& combinations = psParser.GetAllCombinations(); for (HashMap<String, unsigned>::ConstIterator i = combinations.Begin(); i != combinations.End(); ++i) { if (!compileVariation_ || i->first_ == variationName_) { ShaderCombination src = psParser.GetCombination(i->first_); CompiledVariation compile; compile.type_ = PS; compile.name_ = file; compile.outFileName_ = outDir_ + file; if (!src.name_.Empty()) { compile.name_ += "_" + src.name_; compile.outFileName_ += "_" + src.name_; } compile.outFileName_ += useSM3_ ? ".ps3" : ".ps2"; compile.defines_ = src.defines_; compile.defineValues_ = src.defineValues_; variations_.Push(compile); workList_.Push(&variations_.Back()); } } } if (variations_.Empty()) { PrintLine("No variations to compile"); return; } // Load the shader source code { String inputFileName = inDir_ + file + ".hlsl"; File hlslFile(context_, inputFileName); if (!hlslFile.IsOpen()) ErrorExit("Could not open input file " + inputFileName); hlslCode_.Clear(); while (!hlslFile.IsEof()) hlslCode_ += hlslFile.ReadLine() + "\n"; } if (!compileVariation_) { // Create and start worker threads. Use all logical CPUs except one to not lock up the computer completely unsigned numWorkerThreads = GetNumLogicalCPUs() - 1; if (!numWorkerThreads) numWorkerThreads = 1; Vector<SharedPtr<WorkerThread> > workerThreads; workerThreads.Resize(numWorkerThreads); for (unsigned i = 0; i < workerThreads.Size(); ++i) { workerThreads[i] = new WorkerThread(); workerThreads[i]->Run(); } // This will wait until the thread functions have stopped for (unsigned i = 0; i < workerThreads.Size(); ++i) workerThreads[i]->Stop(); } else { WorkerThread dummyThread; dummyThread.ThreadFunction(); } // Check that all shaders compiled for (List<CompiledVariation>::Iterator i = variations_.Begin(); i != variations_.End(); ++i) { if (!i->errorMsg_.Empty()) { if (i->type_ == VS) ErrorExit("Failed to compile vertex shader " + i->name_ + ": " + i->errorMsg_); else ErrorExit("Failed to compile pixel shader " + i->name_ + ": " + i->errorMsg_); } } }
int HHTHSFixedNumIter::update(const Vector &deltaU) { AnalysisModel *theModel = this->getAnalysisModel(); if (theModel == 0) { opserr << "WARNING HHTHSFixedNumIter::update() - no AnalysisModel set\n"; return -1; } ConvergenceTest *theTest = this->getConvergenceTest(); if (theTest == 0) { opserr << "WARNING HHTHSFixedNumIter::update() - no ConvergenceTest set\n"; return -2; } // check domainChanged() has been called, i.e. Ut will not be zero if (Ut == 0) { opserr << "WARNING HHTHSFixedNumIter::update() - domainChange() failed or not called\n"; return -3; } // check deltaU is of correct size if (deltaU.Size() != U->Size()) { opserr << "WARNING HHTHSFixedNumIter::update() - Vectors of incompatible size "; opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endln; return -4; } // get interpolation location and scale displacement increment x = (double) theTest->getNumTests()/theTest->getMaxNumTests(); if (polyOrder == 1) { (*scaledDeltaU) = x*((*U)+deltaU) - (x-1.0)*(*Ut) - (*U); } else if (polyOrder == 2) { (*scaledDeltaU) = x*(x+1.0)/2.0*((*U)+deltaU) - (x-1.0)*(x+1.0)*(*Ut) + (x-1.0)*x/2.0*(*Utm1) - (*U); } else if (polyOrder == 3) { (*scaledDeltaU) = x*(x+1.0)*(x+2.0)/6.0*((*U)+deltaU) - (x-1.0)*(x+1.0)*(x+2.0)/2.0*(*Ut) + (x-1.0)*x*(x+2.0)/2.0*(*Utm1) - (x-1.0)*x*(x+1.0)/6.0*(*Utm2) - (*U); } else { opserr << "WARNING HHTHSFixedNumIter::update() - polyOrder > 3 not supported\n"; } // determine the response at t+deltaT U->addVector(1.0, *scaledDeltaU, c1); Udot->addVector(1.0, *scaledDeltaU, c2); Udotdot->addVector(1.0, *scaledDeltaU, c3); // determine response at t+alpha*deltaT (*Ualpha) = *Ut; Ualpha->addVector((1.0-alphaF), *U, alphaF); (*Ualphadot) = *Utdot; Ualphadot->addVector((1.0-alphaF), *Udot, alphaF); (*Ualphadotdot) = *Utdotdot; Ualphadotdot->addVector((1.0-alphaI), *Udotdot, alphaI); // update the response at the DOFs theModel->setResponse(*Ualpha,*Ualphadot,*Ualphadotdot); if (theModel->updateDomain() < 0) { opserr << "HHTHSFixedNumIter::update() - failed to update the domain\n"; return -5; } return 0; }
void WriteOutput(const String& outputFileName, bool exportAnimations, bool rotationsOnly, bool saveMaterialList) { /// \todo Use save functions of Model & Animation classes // Begin serialization { File dest(context_); if (!dest.Open(outputFileName, FILE_WRITE)) ErrorExit("Could not open output file " + outputFileName); // ID dest.WriteFileID("UMD2"); // Vertexbuffers dest.WriteUInt(vertexBuffers_.Size()); for (unsigned i = 0; i < vertexBuffers_.Size(); ++i) vertexBuffers_[i].WriteData(dest); // Indexbuffers dest.WriteUInt(indexBuffers_.Size()); for (unsigned i = 0; i < indexBuffers_.Size(); ++i) indexBuffers_[i].WriteData(dest); // Subgeometries dest.WriteUInt(subGeometries_.Size()); for (unsigned i = 0; i < subGeometries_.Size(); ++i) { // Write bone mapping info from the first LOD level. It does not change for further LODs dest.WriteUInt(subGeometries_[i][0].boneMapping_.Size()); for (unsigned k = 0; k < subGeometries_[i][0].boneMapping_.Size(); ++k) dest.WriteUInt(subGeometries_[i][0].boneMapping_[k]); // Lod levels for this subgeometry dest.WriteUInt(subGeometries_[i].Size()); for (unsigned j = 0; j < subGeometries_[i].Size(); ++j) { dest.WriteFloat(subGeometries_[i][j].distance_); dest.WriteUInt((unsigned)subGeometries_[i][j].primitiveType_); dest.WriteUInt(subGeometries_[i][j].vertexBuffer_); dest.WriteUInt(subGeometries_[i][j].indexBuffer_); dest.WriteUInt(subGeometries_[i][j].indexStart_); dest.WriteUInt(subGeometries_[i][j].indexCount_); } } // Morphs dest.WriteUInt(morphs_.Size()); for (unsigned i = 0; i < morphs_.Size(); ++i) morphs_[i].WriteData(dest); // Skeleton dest.WriteUInt(bones_.Size()); for (unsigned i = 0; i < bones_.Size(); ++i) { dest.WriteString(bones_[i].name_); dest.WriteUInt(bones_[i].parentIndex_); dest.WriteVector3(bones_[i].bindPosition_); dest.WriteQuaternion(bones_[i].bindRotation_); dest.WriteVector3(bones_[i].bindScale_); Matrix3x4 offsetMatrix(bones_[i].derivedPosition_, bones_[i].derivedRotation_, bones_[i].derivedScale_); offsetMatrix = offsetMatrix.Inverse(); dest.Write(offsetMatrix.Data(), sizeof(Matrix3x4)); dest.WriteUByte(bones_[i].collisionMask_); if (bones_[i].collisionMask_ & 1) dest.WriteFloat(bones_[i].radius_); if (bones_[i].collisionMask_ & 2) dest.WriteBoundingBox(bones_[i].boundingBox_); } // Bounding box dest.WriteBoundingBox(boundingBox_); // Geometry centers for (unsigned i = 0; i < subGeometryCenters_.Size(); ++i) dest.WriteVector3(subGeometryCenters_[i]); } if (saveMaterialList) { String materialListName = ReplaceExtension(outputFileName, ".txt"); File listFile(context_); if (listFile.Open(materialListName, FILE_WRITE)) { for (unsigned i = 0; i < materialNames_.Size(); ++i) { // Assume the materials will be located inside the standard Materials subdirectory listFile.WriteLine("Materials/" + ReplaceExtension(SanitateAssetName(materialNames_[i]), ".xml")); } } else PrintLine("Warning: could not write material list file " + materialListName); } XMLElement skeletonRoot = skelFile_->GetRoot("skeleton"); if (skeletonRoot && exportAnimations) { // Go through animations XMLElement animationsRoot = skeletonRoot.GetChild("animations"); if (animationsRoot) { XMLElement animation = animationsRoot.GetChild("animation"); while (animation) { ModelAnimation newAnimation; newAnimation.name_ = animation.GetAttribute("name"); newAnimation.length_ = animation.GetFloat("length"); XMLElement tracksRoot = animation.GetChild("tracks"); XMLElement track = tracksRoot.GetChild("track"); while (track) { String trackName = track.GetAttribute("bone"); ModelBone* bone = 0; for (unsigned i = 0; i < bones_.Size(); ++i) { if (bones_[i].name_ == trackName) { bone = &bones_[i]; break; } } if (!bone) ErrorExit("Found animation track for unknown bone " + trackName); AnimationTrack newAnimationTrack; newAnimationTrack.name_ = trackName; if (!rotationsOnly) newAnimationTrack.channelMask_ = CHANNEL_POSITION | CHANNEL_ROTATION; else newAnimationTrack.channelMask_ = CHANNEL_ROTATION; XMLElement keyFramesRoot = track.GetChild("keyframes"); XMLElement keyFrame = keyFramesRoot.GetChild("keyframe"); while (keyFrame) { AnimationKeyFrame newKeyFrame; // Convert from right- to left-handed XMLElement position = keyFrame.GetChild("translate"); float x = position.GetFloat("x"); float y = position.GetFloat("y"); float z = position.GetFloat("z"); Vector3 pos(x, y, -z); XMLElement rotation = keyFrame.GetChild("rotate"); XMLElement axis = rotation.GetChild("axis"); float angle = -rotation.GetFloat("angle") * M_RADTODEG; x = axis.GetFloat("x"); y = axis.GetFloat("y"); z = axis.GetFloat("z"); Vector3 axisVec(x, y, -z); Quaternion rot(angle, axisVec); // Transform from bind-pose relative into absolute pos = bone->bindPosition_ + pos; rot = bone->bindRotation_ * rot; newKeyFrame.time_ = keyFrame.GetFloat("time"); newKeyFrame.position_ = pos; newKeyFrame.rotation_ = rot; newAnimationTrack.keyFrames_.Push(newKeyFrame); keyFrame = keyFrame.GetNext("keyframe"); } // Make sure keyframes are sorted from beginning to end Sort(newAnimationTrack.keyFrames_.Begin(), newAnimationTrack.keyFrames_.End(), CompareKeyFrames); // Do not add tracks with no keyframes if (newAnimationTrack.keyFrames_.Size()) newAnimation.tracks_.Push(newAnimationTrack); track = track.GetNext("track"); } // Write each animation into a separate file String animationFileName = outputFileName.Replaced(".mdl", ""); animationFileName += "_" + newAnimation.name_ + ".ani"; File dest(context_); if (!dest.Open(animationFileName, FILE_WRITE)) ErrorExit("Could not open output file " + animationFileName); dest.WriteFileID("UANI"); dest.WriteString(newAnimation.name_); dest.WriteFloat(newAnimation.length_); dest.WriteUInt(newAnimation.tracks_.Size()); for (unsigned i = 0; i < newAnimation.tracks_.Size(); ++i) { AnimationTrack& track = newAnimation.tracks_[i]; dest.WriteString(track.name_); dest.WriteUByte(track.channelMask_); dest.WriteUInt(track.keyFrames_.Size()); for (unsigned j = 0; j < track.keyFrames_.Size(); ++j) { AnimationKeyFrame& keyFrame = track.keyFrames_[j]; dest.WriteFloat(keyFrame.time_); if (track.channelMask_ & CHANNEL_POSITION) dest.WriteVector3(keyFrame.position_); if (track.channelMask_ & CHANNEL_ROTATION) dest.WriteQuaternion(keyFrame.rotation_); if (track.channelMask_ & CHANNEL_SCALE) dest.WriteVector3(keyFrame.scale_); } } animation = animation.GetNext("animation"); PrintLine("Processed animation " + newAnimation.name_); } } } }