summaryrefslogtreecommitdiffstats
path: root/src/Runtime/ogl-runtime/src/importlib/Qt3DSImportMesh.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/ogl-runtime/src/importlib/Qt3DSImportMesh.cpp')
m---------src/Runtime/ogl-runtime0
-rw-r--r--src/Runtime/ogl-runtime/src/importlib/Qt3DSImportMesh.cpp829
2 files changed, 0 insertions, 829 deletions
diff --git a/src/Runtime/ogl-runtime b/src/Runtime/ogl-runtime
new file mode 160000
+Subproject 427fddb50d43aa21a90fc7356ee3cdd8a908df5
diff --git a/src/Runtime/ogl-runtime/src/importlib/Qt3DSImportMesh.cpp b/src/Runtime/ogl-runtime/src/importlib/Qt3DSImportMesh.cpp
deleted file mode 100644
index 1535b911..00000000
--- a/src/Runtime/ogl-runtime/src/importlib/Qt3DSImportMesh.cpp
+++ /dev/null
@@ -1,829 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 1993-2009 NVIDIA Corporation.
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt 3D Studio.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifdef WIN32
-#pragma warning(disable : 4100)
-#endif
-#include "Qt3DSImportLibPrecompile.h"
-#include "Qt3DSImportMesh.h"
-
-using namespace qt3dsimp;
-
-#ifdef QT3DS_X86
-
-// Ensure our objects are of expected sizes. This keeps us honest
-// And ensures that we can load the datastructures we expect to by simply
-// mapping the memory.
-QT3DS_COMPILE_TIME_ASSERT(sizeof(NVRenderComponentTypes::Enum) == 4);
-QT3DS_COMPILE_TIME_ASSERT(sizeof(NVRenderDrawMode::Enum) == 4);
-QT3DS_COMPILE_TIME_ASSERT(sizeof(NVRenderVertexBufferEntry) == 20);
-QT3DS_COMPILE_TIME_ASSERT(sizeof(VertexBuffer) == 20);
-QT3DS_COMPILE_TIME_ASSERT(sizeof(IndexBuffer) == 12);
-QT3DS_COMPILE_TIME_ASSERT(sizeof(MeshSubset) == 40);
-QT3DS_COMPILE_TIME_ASSERT(sizeof(MeshDataHeader) == 12);
-QT3DS_COMPILE_TIME_ASSERT(sizeof(Mesh) == 56);
-
-#endif
-
-#define QT3DSIMP_FOREACH(idxnm, val) \
- for (QT3DSU32 idxnm = 0, __numItems = (QT3DSU32)val; idxnm < __numItems; ++idxnm)
-
-namespace {
-
-struct MeshSubsetV1
-{
- // See description of a logical vertex buffer below
- QT3DSU32 m_LogicalVbufIndex;
- // QT3DS_MAX_U32 means use all available items
- QT3DSU32 m_Count;
- // Offset is in item size, not bytes.
- QT3DSU32 m_Offset;
- // Bounds of this subset. This is filled in by the builder
- // see AddMeshSubset
- NVBounds3 m_Bounds;
-};
-
-struct LogicalVertexBuffer
-{
- QT3DSU32 m_ByteOffset;
- QT3DSU32 m_ByteSize;
- LogicalVertexBuffer(QT3DSU32 byteOff, QT3DSU32 byteSize)
- : m_ByteOffset(byteOff)
- , m_ByteSize(byteSize)
- {
- }
- LogicalVertexBuffer()
- : m_ByteOffset(0)
- , m_ByteSize(0)
- {
- }
-};
-
-struct MeshV1
-{
- VertexBuffer m_VertexBuffer;
- IndexBuffer m_IndexBuffer;
- SOffsetDataRef<LogicalVertexBuffer> m_LogicalVertexBuffers; // may be empty
- SOffsetDataRef<MeshSubsetV1> m_Subsets;
- NVRenderDrawMode::Enum m_DrawMode;
- NVRenderWinding::Enum m_Winding;
- typedef MeshSubsetV1 TSubsetType;
-};
-
-template <typename TSerializer>
-void Serialize(TSerializer &serializer, MeshV1 &mesh)
-{
- QT3DSU8 *baseAddr = reinterpret_cast<QT3DSU8 *>(&mesh);
- serializer.streamify(mesh.m_VertexBuffer.m_Entries);
- serializer.align();
- QT3DSIMP_FOREACH(entry, mesh.m_VertexBuffer.m_Entries.size())
- {
- MeshVertexBufferEntry &entryData = const_cast<MeshVertexBufferEntry &>(
- mesh.m_VertexBuffer.m_Entries.index(baseAddr, entry));
- serializer.streamifyCharPointerOffset(entryData.m_NameOffset);
- serializer.align();
- }
- serializer.streamify(mesh.m_VertexBuffer.m_Data);
- serializer.align();
- serializer.streamify(mesh.m_IndexBuffer.m_Data);
- serializer.align();
- serializer.streamify(mesh.m_LogicalVertexBuffers);
- serializer.align();
- serializer.streamify(mesh.m_Subsets);
- serializer.align();
-}
-
-struct MeshSubsetV2
-{
- QT3DSU32 m_LogicalVbufIndex;
- QT3DSU32 m_Count;
- QT3DSU32 m_Offset;
- NVBounds3 m_Bounds;
- SOffsetDataRef<char16_t> m_Name;
-};
-
-struct MeshV2
-{
- static const char16_t *s_DefaultName;
-
- VertexBuffer m_VertexBuffer;
- IndexBuffer m_IndexBuffer;
- SOffsetDataRef<LogicalVertexBuffer> m_LogicalVertexBuffers; // may be empty
- SOffsetDataRef<MeshSubsetV2> m_Subsets;
- NVRenderDrawMode::Enum m_DrawMode;
- NVRenderWinding::Enum m_Winding;
- typedef MeshSubsetV2 TSubsetType;
-};
-
-template <typename TSerializer>
-void Serialize(TSerializer &serializer, MeshV2 &mesh)
-{
- QT3DSU8 *baseAddr = reinterpret_cast<QT3DSU8 *>(&mesh);
- serializer.streamify(mesh.m_VertexBuffer.m_Entries);
- serializer.align();
- QT3DSIMP_FOREACH(entry, mesh.m_VertexBuffer.m_Entries.size())
- {
- MeshVertexBufferEntry &entryData = const_cast<MeshVertexBufferEntry &>(
- mesh.m_VertexBuffer.m_Entries.index(baseAddr, entry));
- serializer.streamifyCharPointerOffset(entryData.m_NameOffset);
- serializer.align();
- }
- serializer.streamify(mesh.m_VertexBuffer.m_Data);
- serializer.align();
- serializer.streamify(mesh.m_IndexBuffer.m_Data);
- serializer.align();
- serializer.streamify(mesh.m_LogicalVertexBuffers);
- serializer.align();
- serializer.streamify(mesh.m_Subsets);
- serializer.align();
- QT3DSIMP_FOREACH(entry, mesh.m_Subsets.size())
- {
- MeshSubsetV2 &theSubset = const_cast<MeshSubsetV2 &>(mesh.m_Subsets.index(baseAddr, entry));
- serializer.streamify(theSubset.m_Name);
- serializer.align();
- }
-}
-
-// Localize the knowledge required to read/write a mesh into one function
-// written in such a way that you can both read and write by passing
-// in one serializer type or another.
-// This function needs to be careful to request alignment after every write of a
-// buffer that may leave us unaligned. The easiest way to be correct is to request
-// alignment a lot. The hardest way is to use knowledge of the datatypes and
-// only request alignment when necessary.
-template <typename TSerializer>
-void Serialize(TSerializer &serializer, Mesh &mesh)
-{
- QT3DSU8 *baseAddr = reinterpret_cast<QT3DSU8 *>(&mesh);
- serializer.streamify(mesh.m_VertexBuffer.m_Entries);
- serializer.align();
- QT3DSIMP_FOREACH(entry, mesh.m_VertexBuffer.m_Entries.size())
- {
- MeshVertexBufferEntry &entryData = mesh.m_VertexBuffer.m_Entries.index(baseAddr, entry);
- serializer.streamifyCharPointerOffset(entryData.m_NameOffset);
- serializer.align();
- }
- serializer.streamify(mesh.m_VertexBuffer.m_Data);
- serializer.align();
- serializer.streamify(mesh.m_IndexBuffer.m_Data);
- serializer.align();
- serializer.streamify(mesh.m_Subsets);
- serializer.align();
- QT3DSIMP_FOREACH(entry, mesh.m_Subsets.size())
- {
- MeshSubset &theSubset = const_cast<MeshSubset &>(mesh.m_Subsets.index(baseAddr, entry));
- serializer.streamify(theSubset.m_Name);
- serializer.align();
- }
- serializer.streamify(mesh.m_Joints);
- serializer.align();
-}
-
-struct TotallingSerializer
-{
- QT3DSU32 m_NumBytes;
- QT3DSU8 *m_BaseAddress;
- TotallingSerializer(QT3DSU8 *inBaseAddr)
- : m_NumBytes(0)
- , m_BaseAddress(inBaseAddr)
- {
- }
- template <typename TDataType>
- void streamify(const SOffsetDataRef<TDataType> &data)
- {
- m_NumBytes += data.size() * sizeof(TDataType);
- }
- void streamify(const char *data)
- {
- if (data == NULL)
- data = "";
- QT3DSU32 len = (QT3DSU32)strlen(data) + 1;
- m_NumBytes += 4;
- m_NumBytes += len;
- }
- void streamifyCharPointerOffset(QT3DSU32 inOffset)
- {
- if (inOffset) {
- const char *dataPtr = (const char *)(inOffset + m_BaseAddress);
- streamify(dataPtr);
- } else
- streamify("");
- }
- bool needsAlignment() const { return getAlignmentAmount() > 0; }
- QT3DSU32 getAlignmentAmount() const { return 4 - (m_NumBytes % 4); }
- void align()
- {
- if (needsAlignment())
- m_NumBytes += getAlignmentAmount();
- }
-};
-
-struct ByteWritingSerializer
-{
- IOutStream &m_Stream;
- TotallingSerializer m_ByteCounter;
- QT3DSU8 *m_BaseAddress;
- ByteWritingSerializer(IOutStream &str, QT3DSU8 *inBaseAddress)
- : m_Stream(str)
- , m_ByteCounter(inBaseAddress)
- , m_BaseAddress(inBaseAddress)
- {
- }
-
- template <typename TDataType>
- void streamify(const SOffsetDataRef<TDataType> &data)
- {
- m_ByteCounter.streamify(data);
- m_Stream.Write(data.begin(m_BaseAddress), data.size());
- }
- void streamify(const char *data)
- {
- m_ByteCounter.streamify(data);
- if (data == NULL)
- data = "";
- QT3DSU32 len = (QT3DSU32)strlen(data) + 1;
- m_Stream.Write(len);
- m_Stream.Write(data, len);
- }
- void streamifyCharPointerOffset(QT3DSU32 inOffset)
- {
- const char *dataPtr = (const char *)(inOffset + m_BaseAddress);
- streamify(dataPtr);
- }
-
- void align()
- {
- if (m_ByteCounter.needsAlignment()) {
- QT3DSU8 buffer[] = { 0, 0, 0, 0 };
- m_Stream.Write(buffer, m_ByteCounter.getAlignmentAmount());
- m_ByteCounter.align();
- }
- }
-};
-
-struct MemoryAssigningSerializer
-{
- QT3DSU8 *m_Memory;
- QT3DSU8 *m_BaseAddress;
- QT3DSU32 m_Size;
- TotallingSerializer m_ByteCounter;
- bool m_Failure;
- MemoryAssigningSerializer(QT3DSU8 *data, QT3DSU32 size, QT3DSU32 startOffset)
- : m_Memory(data + startOffset)
- , m_BaseAddress(data)
- , m_Size(size)
- , m_ByteCounter(data)
- , m_Failure(false)
- {
- // We expect 4 byte aligned memory to begin with
- QT3DS_ASSERT((((size_t)m_Memory) % 4) == 0);
- }
-
- template <typename TDataType>
- void streamify(const SOffsetDataRef<TDataType> &_data)
- {
- SOffsetDataRef<TDataType> &data = const_cast<SOffsetDataRef<TDataType> &>(_data);
- if (m_Failure) {
- data.m_Size = 0;
- data.m_Offset = 0;
- return;
- }
- QT3DSU32 current = m_ByteCounter.m_NumBytes;
- m_ByteCounter.streamify(_data);
- if (m_ByteCounter.m_NumBytes > m_Size) {
- data.m_Size = 0;
- data.m_Offset = 0;
- m_Failure = true;
- return;
- }
- QT3DSU32 numBytes = m_ByteCounter.m_NumBytes - current;
- if (numBytes) {
- data.m_Offset = (QT3DSU32)(m_Memory - m_BaseAddress);
- updateMemoryBuffer(numBytes);
- } else {
- data.m_Offset = 0;
- data.m_Size = 0;
- }
- }
- void streamify(const char *&_data)
- {
- QT3DSU32 len;
- m_ByteCounter.m_NumBytes += 4;
- if (m_ByteCounter.m_NumBytes > m_Size) {
- _data = "";
- m_Failure = true;
- return;
- }
- qt3ds::intrinsics::memCopy(&len, m_Memory, 4);
- updateMemoryBuffer(4);
- m_ByteCounter.m_NumBytes += len;
- if (m_ByteCounter.m_NumBytes > m_Size) {
- _data = "";
- m_Failure = true;
- return;
- }
- _data = (const char *)m_Memory;
- updateMemoryBuffer(len);
- }
- void streamifyCharPointerOffset(QT3DSU32 &inOffset)
- {
- const char *dataPtr;
- streamify(dataPtr);
- inOffset = (QT3DSU32)(dataPtr - (const char *)m_BaseAddress);
- }
- void align()
- {
- if (m_ByteCounter.needsAlignment()) {
- QT3DSU32 numBytes = m_ByteCounter.getAlignmentAmount();
- m_ByteCounter.align();
- updateMemoryBuffer(numBytes);
- }
- }
- void updateMemoryBuffer(QT3DSU32 numBytes) { m_Memory += numBytes; }
-};
-
-inline QT3DSU32 GetMeshDataSize(Mesh &mesh)
-{
- TotallingSerializer s(reinterpret_cast<QT3DSU8 *>(&mesh));
- Serialize(s, mesh);
- return s.m_NumBytes;
-}
-
-template <typename TDataType>
-QT3DSU32 NextIndex(const QT3DSU8 *inBaseAddress, const SOffsetDataRef<QT3DSU8> data, QT3DSU32 idx)
-{
- QT3DSU32 numItems = data.size() / sizeof(TDataType);
- if (idx < numItems) {
- const TDataType *dataPtr(reinterpret_cast<const TDataType *>(data.begin(inBaseAddress)));
- return dataPtr[idx];
- } else {
- QT3DS_ASSERT(false);
- return 0;
- }
-}
-
-template <typename TDataType>
-QT3DSU32 NextIndex(NVConstDataRef<QT3DSU8> data, QT3DSU32 idx)
-{
- QT3DSU32 numItems = data.size() / sizeof(TDataType);
- if (idx < numItems) {
- const TDataType *dataPtr(reinterpret_cast<const TDataType *>(data.begin()));
- return dataPtr[idx];
- } else {
- QT3DS_ASSERT(false);
- return 0;
- }
-}
-
-inline QT3DSU32 NextIndex(NVConstDataRef<QT3DSU8> inData,
- qt3ds::render::NVRenderComponentTypes::Enum inCompType, QT3DSU32 idx)
-{
- if (inData.size() == 0)
- return idx;
- switch (inCompType) {
- case NVRenderComponentTypes::QT3DSU8:
- return NextIndex<QT3DSU8>(inData, idx);
- case NVRenderComponentTypes::QT3DSI8:
- return NextIndex<QT3DSI8>(inData, idx);
- case NVRenderComponentTypes::QT3DSU16:
- return NextIndex<QT3DSU16>(inData, idx);
- case NVRenderComponentTypes::QT3DSI16:
- return NextIndex<QT3DSI16>(inData, idx);
- case NVRenderComponentTypes::QT3DSU32:
- return NextIndex<QT3DSU32>(inData, idx);
- case NVRenderComponentTypes::QT3DSI32:
- return NextIndex<QT3DSI32>(inData, idx);
- default:
- break;
- }
-
- // Invalid index buffer index type.
- QT3DS_ASSERT(false);
- return 0;
-}
-
-template <typename TMeshType>
-// Not exposed to the outside world
-TMeshType *DoInitialize(MeshBufHeaderFlags /*meshFlags*/, NVDataRef<QT3DSU8> data)
-{
- QT3DSU8 *newMem = data.begin();
- QT3DSU32 amountLeft = data.size() - sizeof(TMeshType);
- MemoryAssigningSerializer s(newMem, amountLeft, sizeof(TMeshType));
- TMeshType *retval = (TMeshType *)newMem;
- Serialize(s, *retval);
- if (s.m_Failure)
- return NULL;
- return retval;
-}
-}
-
-NVBounds3 Mesh::CalculateSubsetBounds(const NVRenderVertexBufferEntry &inEntry,
- NVConstDataRef<QT3DSU8> inVertxData, QT3DSU32 inStride,
- NVConstDataRef<QT3DSU8> inIndexData,
- qt3ds::render::NVRenderComponentTypes::Enum inIndexCompType,
- QT3DSU32 inSubsetCount, QT3DSU32 inSubsetOffset)
-{
- NVBounds3 retval(NVBounds3::empty());
- const NVRenderVertexBufferEntry &entry(inEntry);
- if (entry.m_ComponentType != NVRenderComponentTypes::QT3DSF32 || entry.m_NumComponents != 3) {
- QT3DS_ASSERT(false);
- return retval;
- }
-
- const QT3DSU8 *beginPtr = inVertxData.begin();
- QT3DSU32 numBytes = inVertxData.size();
- QT3DSU32 dataStride = inStride;
- QT3DSU32 posOffset = entry.m_FirstItemOffset;
- // The loop below could be template specialized *if* we wanted to do this.
- // and the perf of the existing loop was determined to be a problem.
- // Else I would rather stay way from the template specialization.
- QT3DSIMP_FOREACH(idx, inSubsetCount)
- {
- QT3DSU32 dataIdx = NextIndex(inIndexData, inIndexCompType, idx + inSubsetOffset);
- QT3DSU32 finalOffset = (dataIdx * dataStride) + posOffset;
- if (finalOffset + sizeof(QT3DSVec3) <= numBytes) {
- const QT3DSU8 *dataPtr = beginPtr + finalOffset;
- retval.include(*reinterpret_cast<const QT3DSVec3 *>(dataPtr));
- } else {
- QT3DS_ASSERT(false);
- }
- }
-
- return retval;
-}
-
-void Mesh::Save(IOutStream &outStream) const
-{
- Mesh &mesh(const_cast<Mesh &>(*this));
- QT3DSU8 *baseAddress = reinterpret_cast<QT3DSU8 *>(&mesh);
- QT3DSU32 numBytes = sizeof(Mesh) + GetMeshDataSize(mesh);
- MeshDataHeader header(numBytes);
- outStream.Write(header);
- outStream.Write(*this);
- ByteWritingSerializer writer(outStream, baseAddress);
- Serialize(writer, mesh);
-}
-
-wchar_t g_DefaultName[] = { 0 };
-
-const wchar_t *Mesh::s_DefaultName = g_DefaultName;
-
-template <typename TMeshType>
-struct SubsetNameHandler
-{
-};
-
-template <>
-struct SubsetNameHandler<MeshV1>
-{
- void AssignName(const QT3DSU8 * /*v1BaseAddress*/, const MeshSubsetV1 & /*mesh*/,
- QT3DSU8 * /*baseAddress*/, QT3DSU8 *& /*nameBuffer*/, MeshSubset &outDest)
- {
- outDest.m_Name = SOffsetDataRef<char16_t>();
- }
- QT3DSU32 NameLength(const MeshSubsetV1 &) { return 0; }
-};
-
-using qt3ds::intrinsics::memCopy;
-
-template <>
-struct SubsetNameHandler<MeshV2>
-{
- void AssignName(const QT3DSU8 *v2BaseAddress, const MeshSubsetV2 &mesh, QT3DSU8 *baseAddress,
- QT3DSU8 *&nameBuffer, MeshSubset &outDest)
- {
- outDest.m_Name.m_Size = mesh.m_Name.m_Size;
- outDest.m_Name.m_Offset = (QT3DSU32)(nameBuffer - baseAddress);
- QT3DSU32 dtypeSize = mesh.m_Name.m_Size * 2;
- memCopy(nameBuffer, mesh.m_Name.begin(v2BaseAddress), dtypeSize);
- nameBuffer += dtypeSize;
- }
- QT3DSU32 NameLength(const MeshSubsetV2 &mesh) { return (mesh.m_Name.size() + 1) * 2; }
-};
-
-QT3DSU32 GetAlignedOffset(QT3DSU32 offset, QT3DSU32 align)
-{
- QT3DSU32 leftover = offset % align;
- if (leftover)
- return offset + (align - leftover);
- return offset;
-}
-
-template <typename TPreviousMeshType>
-Mesh *CreateMeshFromPreviousMesh(TPreviousMeshType *temp, NVAllocatorCallback &alloc)
-{
- QT3DSU32 newMeshSize = sizeof(Mesh);
- QT3DSU8 *tempBaseAddress = reinterpret_cast<QT3DSU8 *>(temp);
- QT3DSU32 alignment = sizeof(void *);
-
- QT3DSU32 vertBufferSize = GetAlignedOffset(temp->m_VertexBuffer.m_Data.size(), alignment);
- newMeshSize += vertBufferSize;
- QT3DSU32 entryDataSize = temp->m_VertexBuffer.m_Entries.size() * sizeof(MeshVertexBufferEntry);
- newMeshSize += entryDataSize;
- QT3DSU32 indexBufferSize = GetAlignedOffset(temp->m_IndexBuffer.m_Data.size(), alignment);
- newMeshSize += indexBufferSize;
- QT3DSU32 entryNameSize = 0;
- for (QT3DSU32 entryIdx = 0, entryEnd = temp->m_VertexBuffer.m_Entries.size(); entryIdx < entryEnd;
- ++entryIdx) {
- const qt3ds::render::NVRenderVertexBufferEntry theEntry =
- temp->m_VertexBuffer.m_Entries.index(tempBaseAddress, entryIdx)
- .ToVertexBufferEntry(tempBaseAddress);
- const char *namePtr = theEntry.m_Name;
- if (namePtr == NULL)
- namePtr = "";
-
- entryNameSize += (QT3DSU32)strlen(theEntry.m_Name) + 1;
- }
- entryNameSize = GetAlignedOffset(entryNameSize, alignment);
-
- newMeshSize += entryNameSize;
- QT3DSU32 subsetBufferSize = temp->m_Subsets.size() * sizeof(MeshSubset);
- newMeshSize += subsetBufferSize;
- QT3DSU32 nameLength = 0;
- for (QT3DSU32 subsetIdx = 0, subsetEnd = temp->m_Subsets.size(); subsetIdx < subsetEnd;
- ++subsetIdx) {
- nameLength += SubsetNameHandler<TPreviousMeshType>().NameLength(
- temp->m_Subsets.index(tempBaseAddress, subsetIdx));
- }
- nameLength = GetAlignedOffset(nameLength, alignment);
-
- newMeshSize += nameLength;
-
- Mesh *retval = (Mesh *)alloc.allocate(newMeshSize, "TempData", __FILE__, __LINE__);
- new (retval) Mesh();
- QT3DSU8 *baseOffset = reinterpret_cast<QT3DSU8 *>(retval);
- QT3DSU8 *vertBufferData = baseOffset + sizeof(Mesh);
- QT3DSU8 *entryBufferData = vertBufferData + vertBufferSize;
- QT3DSU8 *entryNameBuffer = entryBufferData + entryDataSize;
- QT3DSU8 *indexBufferData = entryNameBuffer + entryNameSize;
- QT3DSU8 *subsetBufferData = indexBufferData + indexBufferSize;
- QT3DSU8 *nameData = subsetBufferData + subsetBufferSize;
-
- retval->m_DrawMode = temp->m_DrawMode;
- retval->m_Winding = temp->m_Winding;
- retval->m_VertexBuffer = temp->m_VertexBuffer;
- retval->m_VertexBuffer.m_Data.m_Offset = (QT3DSU32)(vertBufferData - baseOffset);
- retval->m_VertexBuffer.m_Entries.m_Offset = (QT3DSU32)(entryBufferData - baseOffset);
- memCopy(vertBufferData, temp->m_VertexBuffer.m_Data.begin(tempBaseAddress),
- temp->m_VertexBuffer.m_Data.size());
- memCopy(entryBufferData, temp->m_VertexBuffer.m_Entries.begin(tempBaseAddress), entryDataSize);
- QT3DSIMP_FOREACH(idx, temp->m_VertexBuffer.m_Entries.size())
- {
- const MeshVertexBufferEntry &src =
- temp->m_VertexBuffer.m_Entries.index(tempBaseAddress, idx);
- MeshVertexBufferEntry &dest = retval->m_VertexBuffer.m_Entries.index(baseOffset, idx);
-
- const char *targetName = reinterpret_cast<const char *>(src.m_NameOffset + tempBaseAddress);
- if (src.m_NameOffset == 0)
- targetName = "";
- QT3DSU32 nameLen = (QT3DSU32)strlen(targetName) + 1;
- dest.m_NameOffset = (QT3DSU32)(entryNameBuffer - baseOffset);
- memCopy(entryNameBuffer, targetName, nameLen);
- entryNameBuffer += nameLen;
- }
-
- retval->m_IndexBuffer = temp->m_IndexBuffer;
- retval->m_IndexBuffer.m_Data.m_Offset = (QT3DSU32)(indexBufferData - baseOffset);
- memCopy(indexBufferData, temp->m_IndexBuffer.m_Data.begin(tempBaseAddress),
- temp->m_IndexBuffer.m_Data.size());
-
- retval->m_Subsets.m_Size = temp->m_Subsets.m_Size;
- retval->m_Subsets.m_Offset = (QT3DSU32)(subsetBufferData - baseOffset);
- QT3DSIMP_FOREACH(idx, temp->m_Subsets.size())
- {
- MeshSubset &dest = const_cast<MeshSubset &>(retval->m_Subsets.index(baseOffset, idx));
- const typename TPreviousMeshType::TSubsetType &src =
- temp->m_Subsets.index(tempBaseAddress, idx);
- dest.m_Count = src.m_Count;
- dest.m_Offset = src.m_Offset;
- dest.m_Bounds = src.m_Bounds;
- SubsetNameHandler<TPreviousMeshType>().AssignName(tempBaseAddress, src, baseOffset,
- nameData, dest);
- }
- alloc.deallocate(temp);
- return retval;
-}
-
-Mesh *Mesh::Load(NVAllocatorCallback &alloc, IInStream &inStream)
-{
- MeshDataHeader header;
- inStream.Read(header);
- QT3DS_ASSERT(header.m_FileId == MeshDataHeader::GetFileId());
- if (header.m_FileId != MeshDataHeader::GetFileId())
- return NULL;
- if (header.m_FileVersion < 1 || header.m_FileVersion > MeshDataHeader::GetCurrentFileVersion())
- return NULL;
- if (header.m_SizeInBytes < sizeof(Mesh))
- return NULL;
- QT3DSU8 *newMem = (QT3DSU8 *)alloc.allocate(header.m_SizeInBytes, "Mesh", __FILE__, __LINE__);
- QT3DSU32 amountRead = inStream.Read(NVDataRef<QT3DSU8>(newMem, header.m_SizeInBytes));
- if (amountRead != header.m_SizeInBytes)
- goto failure;
-
- if (header.m_FileVersion == 1) {
- MeshV1 *temp = DoInitialize<MeshV1>(header.m_HeaderFlags,
- NVDataRef<QT3DSU8>(newMem, header.m_SizeInBytes));
- if (temp == NULL)
- goto failure;
- return CreateMeshFromPreviousMesh(temp, alloc);
-
- } else if (header.m_FileVersion == 2) {
- MeshV2 *temp = DoInitialize<MeshV2>(header.m_HeaderFlags,
- NVDataRef<QT3DSU8>(newMem, header.m_SizeInBytes));
- if (temp == NULL)
- goto failure;
- return CreateMeshFromPreviousMesh(temp, alloc);
- } else {
- Mesh *retval = Initialize(header.m_FileVersion, header.m_HeaderFlags,
- NVDataRef<QT3DSU8>(newMem, header.m_SizeInBytes));
- if (retval == NULL)
- goto failure;
- return retval;
- }
-
-failure:
- QT3DS_ASSERT(false);
- alloc.deallocate(newMem);
- return NULL;
-}
-
-Mesh *Mesh::Initialize(QT3DSU16 meshVersion, MeshBufHeaderFlags meshFlags, NVDataRef<QT3DSU8> data)
-{
- if (meshVersion != MeshDataHeader::GetCurrentFileVersion())
- return NULL;
- return DoInitialize<Mesh>(meshFlags, data);
-}
-
-// Multimesh support where you have multiple meshes in a single file.
-// Save multi where you have overridden the allocator.
-QT3DSU32 Mesh::SaveMulti(NVAllocatorCallback &alloc, ISeekableIOStream &inStream, QT3DSU32 inId) const
-{
- QT3DSU32 nextId = 1;
- MeshMultiHeader tempHeader;
- MeshMultiHeader *theHeader = NULL;
- MeshMultiHeader *theWriteHeader = NULL;
-
- QT3DSI64 newMeshStartPos = 0;
- if (inStream.GetLength() != 0) {
- theHeader = LoadMultiHeader(alloc, inStream);
- if (theHeader == NULL) {
- QT3DS_ASSERT(false);
- return 0;
- }
- QT3DSU8 *headerBaseAddr = reinterpret_cast<QT3DSU8 *>(theHeader);
- for (QT3DSU32 idx = 0, end = theHeader->m_Entries.size(); idx < end; ++idx) {
- if (inId != 0) {
- QT3DS_ASSERT(inId != theHeader->m_Entries.index(headerBaseAddr, idx).m_MeshId);
- }
- nextId = qMax(nextId, theHeader->m_Entries.index(headerBaseAddr, idx).m_MeshId + 1);
- }
- newMeshStartPos =
- sizeof(MeshMultiHeader) + theHeader->m_Entries.size() * sizeof(MeshMultiEntry);
- theWriteHeader = theHeader;
- } else
- theWriteHeader = &tempHeader;
-
- inStream.SetPosition(-newMeshStartPos, SeekPosition::End);
- QT3DSI64 meshOffset = inStream.GetPosition();
-
- Save(inStream);
-
- if (inId != 0)
- nextId = inId;
- QT3DSU8 *theWriteBaseAddr = reinterpret_cast<QT3DSU8 *>(theWriteHeader);
- // Now write a new header out.
- inStream.Write(theWriteHeader->m_Entries.begin(theWriteBaseAddr),
- theWriteHeader->m_Entries.size());
- MeshMultiEntry newEntry(static_cast<QT3DSI64>(meshOffset), nextId);
- inStream.Write(newEntry);
- theWriteHeader->m_Entries.m_Size++;
- inStream.Write(*theWriteHeader);
-
- if (theHeader != NULL) {
- alloc.deallocate(theHeader);
- }
- return static_cast<QT3DSU32>(nextId);
-}
-
-// Load a single mesh directly from a multi file with the provided overridden items
-SMultiLoadResult Mesh::LoadMulti(NVAllocatorCallback &alloc, ISeekableIOStream &inStream,
- QT3DSU32 inId)
-{
- MeshMultiHeader *theHeader(LoadMultiHeader(alloc, inStream));
- if (theHeader == NULL) {
- return SMultiLoadResult();
- }
- QT3DSU64 fileOffset = (QT3DSU64)-1;
- QT3DSU32 theId = inId;
- QT3DSU8 *theHeaderBaseAddr = reinterpret_cast<QT3DSU8 *>(theHeader);
- bool foundMesh = false;
- for (QT3DSU32 idx = 0, end = theHeader->m_Entries.size(); idx < end && !foundMesh; ++idx) {
- const MeshMultiEntry &theEntry(theHeader->m_Entries.index(theHeaderBaseAddr, idx));
- if (theEntry.m_MeshId == inId || (inId == 0 && theEntry.m_MeshId > theId)) {
- if (theEntry.m_MeshId == inId)
- foundMesh = true;
- theId = qMax(theId, (QT3DSU32)theEntry.m_MeshId);
- fileOffset = theEntry.m_MeshOffset;
- }
- }
- Mesh *retval = NULL;
- if (fileOffset == (QT3DSU64)-1) {
- goto endFunction;
- }
-
- inStream.SetPosition(static_cast<QT3DSI64>(fileOffset), SeekPosition::Begin);
- retval = Load(alloc, inStream);
-endFunction:
- if (theHeader != NULL)
- alloc.deallocate(theHeader);
- return SMultiLoadResult(retval, theId);
-}
-
-// Returns true if this is a multimesh (several meshes in one file).
-bool Mesh::IsMulti(ISeekableIOStream &inStream)
-{
- MeshMultiHeader theHeader;
- inStream.SetPosition(-((QT3DSI64)(sizeof(MeshMultiHeader))), SeekPosition::End);
- QT3DSU32 numBytes = inStream.Read(theHeader);
- if (numBytes != sizeof(MeshMultiHeader))
- return false;
- return theHeader.m_Version == MeshMultiHeader::GetMultiStaticFileId();
-}
-// Load a multi header from a stream.
-MeshMultiHeader *Mesh::LoadMultiHeader(NVAllocatorCallback &alloc, ISeekableIOStream &inStream)
-{
- MeshMultiHeader theHeader;
- inStream.SetPosition(-((QT3DSI64)sizeof(MeshMultiHeader)), SeekPosition::End);
- QT3DSU32 numBytes = inStream.Read(theHeader);
- if (numBytes != sizeof(MeshMultiHeader)
- || theHeader.m_FileId != MeshMultiHeader::GetMultiStaticFileId()
- || theHeader.m_Version > MeshMultiHeader::GetMultiStaticVersion()) {
- return NULL;
- }
- size_t allocSize =
- sizeof(MeshMultiHeader) + theHeader.m_Entries.m_Size * sizeof(MeshMultiEntry);
- MeshMultiHeader *retval =
- (MeshMultiHeader *)alloc.allocate(allocSize, "MeshMultiHeader", __FILE__, __LINE__);
- if (retval == NULL) {
- QT3DS_ASSERT(false);
- return NULL;
- }
- QT3DSU8 *baseAddr = reinterpret_cast<QT3DSU8 *>(retval);
- QT3DSU8 *entryData = baseAddr + sizeof(MeshMultiHeader);
- *retval = theHeader;
- retval->m_Entries.m_Offset = (QT3DSU32)(entryData - baseAddr);
- inStream.SetPosition(-((QT3DSI64)allocSize), SeekPosition::End);
-
- numBytes =
- inStream.Read(reinterpret_cast<MeshMultiEntry *>(entryData), retval->m_Entries.m_Size);
- if (numBytes != retval->m_Entries.m_Size * sizeof(MeshMultiEntry)) {
- QT3DS_ASSERT(false);
- alloc.deallocate(retval);
- retval = NULL;
- }
- return retval;
-}
-
-QT3DSU32 GetHighestId(NVAllocatorCallback &inAlloc, MeshMultiHeader *inHeader)
-{
- if (inHeader == NULL) {
- QT3DS_ASSERT(false);
- return 0;
- }
- QT3DSU8 *baseHeaderAddr = reinterpret_cast<QT3DSU8 *>(inHeader);
- QT3DSU32 highestId = 0;
- for (QT3DSU32 idx = 0, end = inHeader->m_Entries.size(); idx < end; ++idx)
- highestId = qMax(highestId, inHeader->m_Entries.index(baseHeaderAddr, idx).m_MeshId);
- inAlloc.deallocate(inHeader);
- return highestId;
-}
-
-QT3DSU32 Mesh::GetHighestMultiVersion(NVAllocatorCallback &alloc, ISeekableIOStream &inStream)
-{
- return GetHighestId(alloc, LoadMultiHeader(alloc, inStream));
-}