void CSyncCoreObjectMediator::SendCreateObjCmdForConn( CSynConnServer* pConn ) { if(IsActive()) { CSyncCoreObjectDictator::SendCreateObjCmdForConn(pConn); return; } if( m_pFolState ) { CGas2GacOC_Create_Moving_Object cmd; CFPos BeginPixelPos = m_pFolState->GetBeginPixelPos(); CFPos EndPixelPos = m_pFolState->GetEndPixelPos(); cmd.uqbGlobalID = GetGlobalID(); cmd.BeginPixelPos = BeginPixelPos; cmd.EndPixelPos = EndPixelPos; cmd.uqbDelay = IsFollowerDelayEnabled() ? GetFollowerDelay() : 0; cmd.fSpeed = m_pFolState->GetSpeed(); cmd.fMovedDist = m_pFolState->GetMovedDist(); cmd.fEndDist = m_pFolState->GetEndDist(); cmd.usbVarDefCode = static_cast<uint8>(GetVarDefID()); cmd.fBarrierSize = m_fBarrierSize; cmd.usbSelfBarrierType = m_eBarrierType; cmd.uobDistortedFrameTime = GetDistortedTime()->GetDistortedFrameTime(); CPathTransformer pathData(m_pFolState->GetPath()); cmd.udbPathDataLen = pathData.GetDataLenInByte(); pConn->SendCoreCmd( &cmd ); pConn->SendCoreCmd(pathData.GetData(), pathData.GetDataLenInByte()); } else { SendCreateStillObjCmd( eSOF_Follower , pConn ); } }
void CPatchFile::ExecuteDELD(Framework::CStream& stream) { uint32 pathSize = stream.Read32_MSBF(); std::vector<char> pathData(pathSize); stream.Read(pathData.data(), pathSize); std::string path(std::begin(pathData), std::end(pathData)); uint32 otherData[4]; stream.Read(otherData, sizeof(otherData)); auto fullDirPath = m_gameLocationPath / path; fullDirPath.make_preferred(); if(!boost::filesystem::exists(fullDirPath)) { m_result.messages.push_back(string_format("Warning: Directory '%s' deletion requested but directory doesn't exist.", fullDirPath.string().c_str() )); } else { boost::filesystem::remove_all(fullDirPath); } }
void CPatchFile::ExecuteETRY(Framework::CStream& inputStream) { uint32 pathSize = inputStream.Read32_MSBF(); std::vector<char> pathData(pathSize); inputStream.Read(pathData.data(), pathSize); std::string path(std::begin(pathData), std::end(pathData)); auto fullFilePath = m_gameLocationPath / path; auto fullFileDirectory = fullFilePath; fullFileDirectory.remove_leaf(); fullFileDirectory.make_preferred(); fullFilePath.make_preferred(); if(!boost::filesystem::exists(fullFileDirectory)) { m_result.messages.push_back(string_format("Warning: Directory '%s' doesn't exist. Creating.", fullFileDirectory.string().c_str() )); boost::filesystem::create_directories(fullFileDirectory); } if(!boost::filesystem::exists(fullFilePath)) { m_result.messages.push_back(string_format("Warning: File '%s' doesn't exist. Creating.", fullFilePath.string().c_str())); } uint32 itemCount = inputStream.Read32_MSBF(); for(unsigned int i = 0; i < itemCount; i++) { //0x41 = last hash, 0x44 = first hash, 0x4D = both hashes? uint32 hashMode = inputStream.Read32(); assert(hashMode == 0x41 || hashMode == 0x44 || hashMode == 0x4D); uint8 srcFileHash[0x14]; uint8 dstFileHash[0x14]; inputStream.Read(srcFileHash, sizeof(srcFileHash)); inputStream.Read(dstFileHash, sizeof(dstFileHash)); //4E is no compression //5A is zlib compression uint32 compressionMode = inputStream.Read32(); assert((compressionMode == 0x4E) || (compressionMode == 0x5A)); uint32 compressedFileSize = inputStream.Read32_MSBF(); uint32 previousFileSize = inputStream.Read32_MSBF(); uint32 newFileSize = inputStream.Read32_MSBF(); if(i != (itemCount - 1)) { assert(compressedFileSize == 0); } if(compressedFileSize == 0) continue; //Data starts here { //Retrying here because explorer.exe can sometimes open the ffxiv*.exe files to load //the icons making the open operation fail if we need to patch it again. auto outputStream = CreateOutputStdStreamWithRetry(fullFilePath.native()); if(compressionMode == 0x4E) { ExtractUncompressed(outputStream, inputStream, compressedFileSize); } else if(compressionMode == 0x5A) { ExtractCompressed(outputStream, inputStream, compressedFileSize); } else { throw std::runtime_error("Unknown compression type."); } } } inputStream.Seek(0x08, Framework::STREAM_SEEK_CUR); }
void process(const WorkUnit *workUnit, WorkResult *workResult, const bool &stop) { const RectangularWorkUnit *rect = static_cast<const RectangularWorkUnit *>(workUnit); GBDPTWorkResult *result = static_cast<GBDPTWorkResult *>(workResult); bool needsTimeSample = m_sensor->needsTimeSample(); Float time = m_sensor->getShutterOpen(); result->setOffset(rect->getOffset()); result->setSize(rect->getSize()); result->clear(); m_hilbertCurve.initialize(TVector2<uint8_t>(rect->getSize())); Path emitterSubpath; Path sensorSubpath; /*shift direction is hard-coded. future releases should support arbitrary kernels. */ Vector2 shifts[4] = { Vector2(0, -1), Vector2(-1, 0), Vector2(1, 0), Vector2(0, 1) }; if (m_config.maxDepth == -1){ Log(EWarn, "maxDepth is unlimited, set to 12!"); m_config.maxDepth = 12; } /* Determine the necessary random walk depths based on properties of the endpoints */ int emitterDepth = m_config.maxDepth, sensorDepth = m_config.maxDepth; //marco: ensure some required properties (temporary solution) m_config.sampleDirect = false; /* Go one extra step if the sensor can be intersected */ if (!m_scene->hasDegenerateSensor() && emitterDepth != -1) ++emitterDepth; /* Sensor subpath legth +1 if there are emitters that can be intersected (to allow very direct sensor paths)*/ if (!m_scene->hasDegenerateEmitters() && sensorDepth != -1) ++sensorDepth; /*loop over pixels in block*/ for (size_t i = 0; i<m_hilbertCurve.getPointCount(); ++i) { int neighborCount = m_config.nNeighbours; std::vector<ShiftPathData> pathData(neighborCount+1, sensorDepth+3); pathData[0].success = true; pathData[0].couldConnectAfterB = true; /*allocate memory depending on number of neighbours*/ std::vector<Path> emitterSubpath(neighborCount + 1); std::vector<Path> sensorSubpath(neighborCount + 1); std::vector<double> jacobianLP(neighborCount); std::vector<double> genGeomTermLP(neighborCount + 1); std::vector<Spectrum> value(neighborCount + 1); std::vector<Float> miWeight(neighborCount + 1); std::vector<Float> valuePdf(neighborCount + 1); bool *pathSuccess = (bool *)alloca((neighborCount + 1) * sizeof(bool)); Point2 samplePos; Point2i offset = Point2i(m_hilbertCurve[i]) + Vector2i(rect->getOffset()); m_sampler->generate(offset); int spp = m_sampler->getSampleCount(); /* For each sample */ for (size_t j = 0; j<spp; j++) { if (stop) break; if (needsTimeSample) time = m_sensor->sampleTime(m_sampler->next1D()); /* Start new emitter and sensor subpaths */ emitterSubpath[0].initialize(m_scene, time, EImportance, m_pool); sensorSubpath[0].initialize(m_scene, time, ERadiance, m_pool); /* Perform a random walk using alternating steps on each path */ Path::alternatingRandomWalkFromPixel(m_scene, m_sampler, emitterSubpath[0], emitterDepth, sensorSubpath[0], sensorDepth, offset, m_config.rrDepth, m_pool); samplePos = sensorSubpath[0].vertex(1)->getSamplePosition(); double jx, jy; //marco: Hack- Required to store negative gradients... for (size_t i = 0; i < (1 + m_config.nNeighbours); ++i){ const_cast<ImageBlock *>(result->getImageBlock(i))->setAllowNegativeValues(true); if (m_config.lightImage) const_cast<ImageBlock *>(result->getLightImage(i))->setAllowNegativeValues(true); } Path connectPath; int ptx; /* create shift-able path */ bool couldConnect = createShiftablePath(connectPath, emitterSubpath[0], sensorSubpath[0], 1, sensorSubpath[0].vertexCount() - 1, ptx); /* geometry term(s) of base */ m_offsetGenerator->computeMuRec(connectPath, pathData[0].muRec); int idx = 0; for (int v = pathData[0].muRec.extra[0] - 1; v >= 0; v--){ int idx = connectPath.vertexCount() - 1 - v; if (Path::isConnectable_GBDPT(connectPath.vertex(v), m_config.m_shiftThreshold) && v >= pathData[0].muRec.extra[2]) pathData[0].genGeomTerm.at(idx) = connectPath.calcSpecularPDFChange(v, m_offsetGenerator); else pathData[0].genGeomTerm.at(idx) = pathData[0].genGeomTerm.at(idx - 1); } /*shift base path if possible*/ for (int k = 0; k<neighborCount; k++){ //we cannot shift very direct paths! pathData[k + 1].success = pathData[0].muRec.extra[0] <= 2 ? false : m_offsetGenerator->generateOffsetPathGBDPT(connectPath, sensorSubpath[k + 1], pathData[k + 1].muRec, shifts[k], pathData[k + 1].couldConnectAfterB, false); //if shift successful, compute jacobian and geometry term for each possible connection strategy that affects the shifted sub path //for the manifold exploration shift there are only two connectible vertices in the affected chain (v_b and v_c) if (pathData[k + 1].success){ int idx = 0; int a, b, c; for (int v = pathData[k + 1].muRec.extra[0] - 1; v >= 0; v--){ int idx = connectPath.vertexCount() - 1 - v; if (Path::isConnectable_GBDPT(connectPath.vertex(v), m_config.m_shiftThreshold) && v >= pathData[k + 1].muRec.extra[2]){ a = pathData[k + 1].muRec.extra[0]; b = v >= pathData[k + 1].muRec.extra[1] ? v : pathData[k + 1].muRec.extra[1]; c = v >= pathData[k + 1].muRec.extra[1] ? v - 1 : pathData[k + 1].muRec.extra[2]; jx = connectPath.halfJacobian_GBDPT(a, b, c, m_offsetGenerator); jy = sensorSubpath[k + 1].halfJacobian_GBDPT(a, b, c, m_offsetGenerator); pathData[k+1].jacobianDet.at(idx) = jy / jx; pathData[k+1].genGeomTerm.at(idx) = sensorSubpath[k + 1].calcSpecularPDFChange(v, m_offsetGenerator); } else{ pathData[k + 1].jacobianDet.at(idx) = pathData[k + 1].jacobianDet.at(idx - 1); pathData[k + 1].genGeomTerm.at(idx) = pathData[k + 1].genGeomTerm.at(idx - 1); } } } sensorSubpath[k + 1].reverse(); } /*save index of vertex b for evaluation (indexing is reversed)*/ int v_b = connectPath.vertexCount() - 1 - pathData[0].muRec.extra[1]; /* evaluate base and offset paths */ evaluate(result, emitterSubpath[0], sensorSubpath, pathData, v_b, value, miWeight, valuePdf, jacobianLP, genGeomTermLP, pathSuccess); /* clean up memory */ connectPath.release(ptx, ptx + 2, m_pool); for (int k = 0; k<neighborCount; k++){ if (pathData[k+1].success){ sensorSubpath[k + 1].reverse(); sensorSubpath[k + 1].release(pathData[k + 1].muRec.l, pathData[k + 1].muRec.m + 1, m_pool); } } sensorSubpath[0].release(m_pool); emitterSubpath[0].release(m_pool); for (size_t i = 0; i < (1 + m_config.nNeighbours); ++i){ const_cast<ImageBlock *>(result->getImageBlock(i))->setAllowNegativeValues(false); if (m_config.lightImage) const_cast<ImageBlock *>(result->getLightImage(i))->setAllowNegativeValues(false); } m_sampler->advance(); } } /* Make sure that there were no memory leaks */ Assert(m_pool.unused()); }