ezResult ezImageConversion::Convert(const ezImageView& source, ezImage& target, ezArrayPtr<ConversionPathNode> path, ezUInt32 numScratchBuffers) { EZ_ASSERT_DEV(path.GetCount() > 0, "Invalid conversion path"); EZ_ASSERT_DEV(path[0].m_sourceFormat == source.GetImageFormat(), "Invalid conversion path"); ezHybridArray<ezImage, 16> intermediates; intermediates.SetCount(numScratchBuffers); const ezImageView* pSource = &source; for (ezUInt32 i = 0; i < path.GetCount(); ++i) { ezUInt32 targetIndex = path[i].m_targetBufferIndex; ezImage* pTarget = targetIndex == 0 ? &target : &intermediates[targetIndex - 1]; if (ConvertSingleStep(path[i].m_step, *pSource, *pTarget, path[i].m_targetFormat).Failed()) { return EZ_FAILURE; } pSource = pTarget; } return EZ_SUCCESS; }
static ezResult DecompressZStd(ezArrayPtr<const ezUInt8> pCompressedData, ezDynamicArray<ezUInt8>& out_Data) { size_t uiSize = ZSTD_findDecompressedSize(pCompressedData.GetPtr(), pCompressedData.GetCount()); if (uiSize == ZSTD_CONTENTSIZE_ERROR) { ezLog::Error("Can't decompress since it wasn't compressed with ZStd"); return EZ_FAILURE; } else if (uiSize == ZSTD_CONTENTSIZE_UNKNOWN) { ezLog::Error("Can't decompress since the original size can't be determined, was the data compressed using the streaming variant?"); return EZ_FAILURE; } if (uiSize > std::numeric_limits<ezUInt32>::max()) { ezLog::Error("Can't compress since the output container can't hold enough elements ({0})", static_cast<ezUInt64>(uiSize)); return EZ_FAILURE; } out_Data.SetCountUninitialized(static_cast<ezUInt32>(uiSize)); size_t const uiActualSize = ZSTD_decompress(out_Data.GetData(), uiSize, pCompressedData.GetPtr(), pCompressedData.GetCount()); if (uiActualSize != uiSize) { ezLog::Error("Error during ZStd decompression: '{0}'.", ZSTD_getErrorName(uiActualSize)); return EZ_FAILURE; } return EZ_SUCCESS; }
ezResult ezImageConversion::ConvertRaw(ezArrayPtr<const void> source, ezArrayPtr<void> target, ezUInt32 numElements, ezArrayPtr<ConversionPathNode> path, ezUInt32 numScratchBuffers) { EZ_ASSERT_DEV(path.GetCount() > 0, "Path of length 0 is invalid."); if (numElements == 0) { return EZ_SUCCESS; } if (ezImageFormat::IsCompressed(path.GetPtr()->m_sourceFormat) || ezImageFormat::IsCompressed((path.GetEndPtr() - 1)->m_targetFormat)) { return EZ_FAILURE; } ezHybridArray<ezDynamicArray<char>, 16> intermediates; intermediates.SetCount(numScratchBuffers); for (ezUInt32 i = 0; i < path.GetCount(); ++i) { ezUInt32 targetIndex = path[i].m_targetBufferIndex; ezUInt32 targetBpp = ezImageFormat::GetBitsPerPixel(path[i].m_targetFormat); ezArrayPtr<void> stepTarget; if (targetIndex == 0) { stepTarget = target; } else { ezUInt32 expectedSize = static_cast<ezUInt32>(targetBpp * numElements / 8); intermediates[targetIndex - 1].SetCount(expectedSize); stepTarget = ezArrayPtr<void>(intermediates[targetIndex - 1].GetData(), intermediates[targetIndex - 1].GetCount()); } if (path[i].m_step == nullptr) { memcpy(stepTarget.GetPtr(), source.GetPtr(), numElements * targetBpp / 8); } else { if (static_cast<const ezImageConversionStepLinear*>(path[i].m_step) ->ConvertPixels(source, stepTarget, numElements, path[i].m_sourceFormat, path[i].m_targetFormat) .Failed()) { return EZ_FAILURE; } } source = stepTarget; } return EZ_SUCCESS; }
ezResult ezImageConversion::ConvertRaw(ezArrayPtr<const void> source, ezArrayPtr<void> target, ezUInt32 numElements, ezImageFormat::Enum sourceFormat, ezImageFormat::Enum targetFormat) { if (numElements == 0) { return EZ_SUCCESS; } // Trivial copy if (sourceFormat == targetFormat) { if (target.GetPtr() != source.GetPtr()) memcpy(target.GetPtr(), source.GetPtr(), numElements * ezUInt64(ezImageFormat::GetBitsPerPixel(sourceFormat)) / 8); return EZ_SUCCESS; } if (ezImageFormat::IsCompressed(sourceFormat) || ezImageFormat::IsCompressed(targetFormat)) { return EZ_FAILURE; } ezHybridArray<ConversionPathNode, 16> path; ezUInt32 numScratchBuffers; if (BuildPath(sourceFormat, targetFormat, source.GetPtr() == target.GetPtr(), path, numScratchBuffers).Failed()) { return EZ_FAILURE; } return ConvertRaw(source, target, numElements, path, numScratchBuffers); }
static ezResult CompressZStd(ezArrayPtr<const ezUInt8> pUncompressedData, ezDynamicArray<ezUInt8>& out_Data) { size_t uiSizeBound = ZSTD_compressBound(pUncompressedData.GetCount()); if(uiSizeBound > std::numeric_limits<ezUInt32>::max()) { ezLog::Error("Can't compress since the output container can't hold enough elements ({0})", static_cast<ezUInt64>(uiSizeBound)); return EZ_FAILURE; } out_Data.SetCountUninitialized(static_cast<ezUInt32>(uiSizeBound)); size_t const cSize = ZSTD_compress(out_Data.GetData(), uiSizeBound, pUncompressedData.GetPtr(), pUncompressedData.GetCount(), 1); if (ZSTD_isError(cSize)) { ezLog::Error("Compression failed with error: '{0}'.", ZSTD_getErrorName(cSize)); return EZ_FAILURE; } out_Data.SetCount(static_cast<ezUInt32>(cSize)); return EZ_SUCCESS; }
void ezWorld::DeleteObjectNow(const ezGameObjectHandle& object) { CheckForWriteAccess(); ezGameObject* pObject = nullptr; if (!m_Data.m_Objects.TryGetValue(object, pObject)) return; // set object to inactive so components and children know that they shouldn't access the object anymore. pObject->m_Flags.Remove(ezObjectFlags::Active); // delete children for (auto it = pObject->GetChildren(); it.IsValid(); ++it) { DeleteObjectNow(it->GetHandle()); } // delete attached components const ezArrayPtr<ezComponent*> components = pObject->m_Components; for (ezUInt32 c = 0; c < components.GetCount(); ++c) { ezComponent* pComponent = components[c]; pComponent->GetOwningManager()->DeleteComponent(pComponent->GetHandle()); } EZ_ASSERT_DEV(pObject->m_Components.GetCount() == 0, "Components should already be removed"); // fix parent and siblings UnlinkFromParent(pObject); // remove from global key tables SetObjectGlobalKey(pObject, ezHashedString()); // invalidate and remove from id table pObject->m_InternalId.Invalidate(); m_Data.m_DeadObjects.PushBack(pObject); EZ_VERIFY(m_Data.m_Objects.Remove(object), "Implementation error."); }
ezResult Decompress(ezArrayPtr<const ezUInt8> pCompressedData, ezCompressionMethod eMethod, ezDynamicArray<ezUInt8>& out_Data) { out_Data.Clear(); if (pCompressedData.IsEmpty()) { return EZ_SUCCESS; } switch (eMethod) { case ezCompressionMethod::ZStd: #ifdef BUILDSYSTEM_ENABLE_ZSTD_SUPPORT return DecompressZStd(pCompressedData, out_Data); #else ezLog::Error("ZStd compression disabled in build settings!"); return EZ_FAILURE; #endif default: ezLog::Error("Unsupported compression method {0}!", static_cast<ezUInt32>(eMethod)); return EZ_FAILURE; } }
ezImageFormat::Enum ezImageConversion::FindClosestCompatibleFormat(ezImageFormat::Enum format, ezArrayPtr<const ezImageFormat::Enum> compatibleFormats) { if (!s_conversionTableValid) { RebuildConversionTable(); } TableEntry bestEntry; ezImageFormat::Enum bestFormat = ezImageFormat::UNKNOWN; for (ezUInt32 targetIndex = 0; targetIndex < ezUInt32(compatibleFormats.GetCount()); targetIndex++) { ezUInt32 tableIndex = MakeKey(format, compatibleFormats[targetIndex]); TableEntry candidate; if (s_conversionTable.TryGetValue(tableIndex, candidate) && candidate < bestEntry) { bestEntry = candidate; bestFormat = compatibleFormats[targetIndex]; } } return bestFormat; }
void ezExpressionVM::Execute(const ezExpressionByteCode& byteCode, ezArrayPtr<const ezExpression::Stream> inputs, ezArrayPtr<ezExpression::Stream> outputs, ezUInt32 uiNumInstances) { // Input mapping { auto inputNames = byteCode.GetInputs(); m_InputMapping.Clear(); m_InputMapping.Reserve(inputNames.GetCount()); for (auto& inputName : inputNames) { bool bInputFound = false; for (ezUInt32 i = 0; i < inputs.GetCount(); ++i) { if (inputs[i].m_sName == inputName) { inputs[i].ValidateDataSize(uiNumInstances, "Input"); m_InputMapping.PushBack(i); bInputFound = true; break; } } EZ_ASSERT_DEV(bInputFound, "Bytecode expects an input '{0}'", inputName); } } // Output mapping { auto outputNames = byteCode.GetOutputs(); m_OutputMapping.Clear(); m_OutputMapping.Reserve(outputNames.GetCount()); for (auto& outputName : outputNames) { bool bOutputFound = false; for (ezUInt32 i = 0; i < outputs.GetCount(); ++i) { if (outputs[i].m_sName == outputName) { outputs[i].ValidateDataSize(uiNumInstances, "Output"); m_OutputMapping.PushBack(i); bOutputFound = true; break; } } EZ_ASSERT_DEV(bOutputFound, "Bytecode expects an output '{0}'", outputName); } } ezSimdVec4f* pRegisters = m_Registers.GetData(); const ezUInt32 uiNumRegisters = (uiNumInstances + 3) / 4; const ezUInt32 uiLastInstanceIndex = uiNumInstances - 1; const ezUInt32 uiTotalNumRegisters = byteCode.GetNumTempRegisters() * uiNumRegisters; if (uiTotalNumRegisters > m_Registers.GetCount()) { EZ_REPORT_FAILURE("Not enough registers to execute bytecode. Needs {0} but only has {1}.", uiTotalNumRegisters, m_Registers.GetCount()); return; } // Execute bytecode const ezExpressionByteCode::StorageType* pByteCode = byteCode.GetByteCode(); const ezExpressionByteCode::StorageType* pByteCodeEnd = byteCode.GetByteCodeEnd(); while (pByteCode < pByteCodeEnd) { ezExpressionByteCode::OpCode::Enum opCode = ezExpressionByteCode::GetOpCode(pByteCode); switch (opCode) { // unary case ezExpressionByteCode::OpCode::Abs_R: VMOperation1(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x.Abs(); }); break; case ezExpressionByteCode::OpCode::Sqrt_R: VMOperation1(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x.GetSqrt(); }); break; case ezExpressionByteCode::OpCode::Mov_R: VMOperation1(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x; }); break; case ezExpressionByteCode::OpCode::Mov_C: VMOperation1_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x; }); break; case ezExpressionByteCode::OpCode::Mov_I: VMLoadInput(pByteCode, pRegisters, uiNumRegisters, inputs, m_InputMapping); break; case ezExpressionByteCode::OpCode::Mov_O: VMStoreOutput(pByteCode, pRegisters, uiNumRegisters, outputs, m_OutputMapping); break; // binary case ezExpressionByteCode::OpCode::Add_RR: VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a + b; }); break; case ezExpressionByteCode::OpCode::Add_CR: VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a + b; }); break; case ezExpressionByteCode::OpCode::Sub_RR: VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a - b; }); break; case ezExpressionByteCode::OpCode::Sub_CR: VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a - b; }); break; case ezExpressionByteCode::OpCode::Mul_RR: VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMul(b); }); break; case ezExpressionByteCode::OpCode::Mul_CR: VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMul(b); }); break; case ezExpressionByteCode::OpCode::Div_RR: VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompDiv(b); }); break; case ezExpressionByteCode::OpCode::Div_CR: VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompDiv(b); }); break; case ezExpressionByteCode::OpCode::Min_RR: VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMin(b); }); break; case ezExpressionByteCode::OpCode::Min_CR: VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMin(b); }); break; case ezExpressionByteCode::OpCode::Max_RR: VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMax(b); }); break; case ezExpressionByteCode::OpCode::Max_CR: VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMax(b); }); break; // call case ezExpressionByteCode::OpCode::Call: VMCall(pByteCode, pRegisters, uiNumRegisters); break; default: EZ_ASSERT_NOT_IMPLEMENTED; return; } } }
int GetNumFaces() const { return triangles.GetCount(); }
#include <PCH.h> #include <Foundation/Containers/DynamicArray.h> EZ_CREATE_SIMPLE_TEST(Basics, ArrayPtr) { EZ_TEST_BLOCK(ezTestBlock::Enabled, "Empty Constructor") { ezArrayPtr<ezInt32> Empty; EZ_TEST_BOOL(Empty.GetPtr() == nullptr); EZ_TEST_BOOL(Empty.GetCount() == 0); } EZ_TEST_BLOCK(ezTestBlock::Enabled, "Constructor") { ezInt32 pIntData[] = { 1, 2, 3, 4, 5 }; ezArrayPtr<ezInt32> ap(pIntData, 3); EZ_TEST_BOOL(ap.GetPtr() == pIntData); EZ_TEST_BOOL(ap.GetCount() == 3); ezArrayPtr<ezInt32> ap2(pIntData, 0); EZ_TEST_BOOL(ap2.GetPtr() == nullptr); EZ_TEST_BOOL(ap2.GetCount() == 0); ezArrayPtr<ezInt32> ap3(pIntData); EZ_TEST_BOOL(ap3.GetPtr() == pIntData); EZ_TEST_BOOL(ap3.GetCount() == 5); ezArrayPtr<ezInt32> ap4(ap); EZ_TEST_BOOL(ap4.GetPtr() == pIntData);