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 );
	}
}
Beispiel #2
0
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);
	}
}
Beispiel #3
0
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());
	}