243 lines
7.2 KiB
C++
243 lines
7.2 KiB
C++
//
|
|
// Copyright (c) 2008-2021 the Urho3D project.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include <Urho3D/Graphics/Animation.h>
|
|
#include <Urho3D/Math/BoundingBox.h>
|
|
#include <Urho3D/Graphics/Graphics.h>
|
|
#include <Urho3D/Graphics/VertexBuffer.h>
|
|
#include <Urho3D/IO/Serializer.h>
|
|
#include <Urho3D/Math/Matrix3x4.h>
|
|
|
|
using namespace Urho3D;
|
|
|
|
struct Triangle
|
|
{
|
|
Triangle(unsigned v0, unsigned v1, unsigned v2) :
|
|
v0_{v0},
|
|
v1_{v1},
|
|
v2_{v2}
|
|
{
|
|
}
|
|
|
|
unsigned v0_;
|
|
unsigned v1_;
|
|
unsigned v2_;
|
|
};
|
|
|
|
struct ModelBone
|
|
{
|
|
String name_;
|
|
unsigned parentIndex_;
|
|
Vector3 bindPosition_;
|
|
Quaternion bindRotation_;
|
|
Vector3 bindScale_;
|
|
Vector3 derivedPosition_;
|
|
Quaternion derivedRotation_;
|
|
Vector3 derivedScale_;
|
|
Matrix3x4 worldTransform_;
|
|
Matrix3x4 inverseWorldTransform_;
|
|
unsigned char collisionMask_;
|
|
float radius_;
|
|
BoundingBox boundingBox_;
|
|
};
|
|
|
|
struct ModelAnimation
|
|
{
|
|
String name_;
|
|
float length_;
|
|
Vector<AnimationTrack> tracks_;
|
|
};
|
|
|
|
struct BoneWeightAssignment
|
|
{
|
|
BoneWeightAssignment(unsigned char boneIndex, float weight) :
|
|
boneIndex_{boneIndex},
|
|
weight_{weight}
|
|
{
|
|
}
|
|
|
|
unsigned char boneIndex_;
|
|
float weight_;
|
|
};
|
|
|
|
bool CompareWeights(const BoneWeightAssignment& lhs, const BoneWeightAssignment& rhs)
|
|
{
|
|
return lhs.weight_ > rhs.weight_;
|
|
}
|
|
|
|
bool CompareKeyFrames(const AnimationKeyFrame& lhs, const AnimationKeyFrame& rhs)
|
|
{
|
|
return lhs.time_ < rhs.time_;
|
|
}
|
|
|
|
struct ModelVertex
|
|
{
|
|
Vector3 position_;
|
|
Vector3 normal_;
|
|
Color color_;
|
|
Vector2 texCoord1_;
|
|
Vector2 texCoord2_;
|
|
Vector3 cubeTexCoord1_;
|
|
Vector3 cubeTexCoord2_;
|
|
Vector4 tangent_;
|
|
float blendWeights_[4]{};
|
|
unsigned char blendIndices_[4]{};
|
|
bool hasBlendWeights_{};
|
|
unsigned useCount_{};
|
|
int cachePosition_{};
|
|
float score_{};
|
|
};
|
|
|
|
struct ModelVertexBuffer
|
|
{
|
|
VertexMaskFlags elementMask_;
|
|
unsigned morphStart_;
|
|
unsigned morphCount_;
|
|
Vector<ModelVertex> vertices_;
|
|
|
|
ModelVertexBuffer() :
|
|
elementMask_(MASK_NONE),
|
|
morphStart_(0),
|
|
morphCount_(0)
|
|
{
|
|
}
|
|
|
|
void WriteData(Serializer& dest)
|
|
{
|
|
dest.WriteUInt(vertices_.Size());
|
|
|
|
PODVector<VertexElement> elements = VertexBuffer::GetElements(elementMask_);
|
|
dest.WriteUInt(elements.Size());
|
|
for (unsigned j = 0; j < elements.Size(); ++j)
|
|
{
|
|
unsigned elementDesc = ((unsigned)elements[j].type_) |
|
|
(((unsigned)elements[j].semantic_) << 8u) |
|
|
(((unsigned)elements[j].index_) << 16u);
|
|
dest.WriteUInt(elementDesc);
|
|
}
|
|
|
|
dest.WriteUInt(morphStart_);
|
|
dest.WriteUInt(morphCount_);
|
|
|
|
for (unsigned i = 0; i < vertices_.Size(); ++i)
|
|
{
|
|
if (elementMask_ & MASK_POSITION)
|
|
dest.WriteVector3(vertices_[i].position_);
|
|
if (elementMask_ & MASK_NORMAL)
|
|
dest.WriteVector3(vertices_[i].normal_);
|
|
if (elementMask_ & MASK_COLOR)
|
|
dest.WriteUInt(vertices_[i].color_.ToUInt());
|
|
if (elementMask_ & MASK_TEXCOORD1)
|
|
dest.WriteVector2(vertices_[i].texCoord1_);
|
|
if (elementMask_ & MASK_TEXCOORD2)
|
|
dest.WriteVector2(vertices_[i].texCoord2_);
|
|
if (elementMask_ & MASK_CUBETEXCOORD1)
|
|
dest.WriteVector3(vertices_[i].cubeTexCoord1_);
|
|
if (elementMask_ & MASK_CUBETEXCOORD2)
|
|
dest.WriteVector3(vertices_[i].cubeTexCoord2_);
|
|
if (elementMask_ & MASK_TANGENT)
|
|
dest.WriteVector4(vertices_[i].tangent_);
|
|
if (elementMask_ & MASK_BLENDWEIGHTS)
|
|
dest.Write(&vertices_[i].blendWeights_[0], 4 * sizeof(float));
|
|
if (elementMask_ & MASK_BLENDINDICES)
|
|
dest.Write(&vertices_[i].blendIndices_[0], 4 * sizeof(unsigned char));
|
|
}
|
|
}
|
|
};
|
|
|
|
struct ModelMorphBuffer
|
|
{
|
|
unsigned vertexBuffer_;
|
|
unsigned elementMask_;
|
|
Vector<Pair<unsigned, ModelVertex> > vertices_;
|
|
};
|
|
|
|
struct ModelMorph
|
|
{
|
|
String name_;
|
|
Vector<ModelMorphBuffer> buffers_;
|
|
|
|
void WriteData(Serializer& dest)
|
|
{
|
|
dest.WriteString(name_);
|
|
dest.WriteUInt(buffers_.Size());
|
|
for (unsigned i = 0; i < buffers_.Size(); ++i)
|
|
{
|
|
dest.WriteUInt(buffers_[i].vertexBuffer_);
|
|
dest.WriteUInt(buffers_[i].elementMask_);
|
|
dest.WriteUInt(buffers_[i].vertices_.Size());
|
|
unsigned elementMask = buffers_[i].elementMask_;
|
|
|
|
for (Vector<Pair<unsigned, ModelVertex> >::Iterator j = buffers_[i].vertices_.Begin();
|
|
j != buffers_[i].vertices_.End(); ++j)
|
|
{
|
|
dest.WriteUInt(j->first_);
|
|
if (elementMask & MASK_POSITION)
|
|
dest.WriteVector3(j->second_.position_);
|
|
if (elementMask & MASK_NORMAL)
|
|
dest.WriteVector3(j->second_.normal_);
|
|
if (elementMask & MASK_TANGENT)
|
|
dest.WriteVector3(Vector3(j->second_.tangent_.x_, j->second_.tangent_.y_, j->second_.tangent_.z_));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
struct ModelIndexBuffer
|
|
{
|
|
unsigned indexSize_;
|
|
PODVector<unsigned> indices_;
|
|
|
|
ModelIndexBuffer() :
|
|
indexSize_(sizeof(unsigned short))
|
|
{
|
|
}
|
|
|
|
void WriteData(Serializer& dest)
|
|
{
|
|
dest.WriteUInt(indices_.Size());
|
|
dest.WriteUInt(indexSize_);
|
|
|
|
for (unsigned i = 0; i < indices_.Size(); ++i)
|
|
{
|
|
if (indexSize_ == sizeof(unsigned short))
|
|
dest.WriteUShort(indices_[i]);
|
|
else
|
|
dest.WriteUInt(indices_[i]);
|
|
}
|
|
}
|
|
};
|
|
|
|
struct ModelSubGeometryLodLevel
|
|
{
|
|
float distance_{};
|
|
PrimitiveType primitiveType_{TRIANGLE_LIST};
|
|
unsigned vertexBuffer_{};
|
|
unsigned indexBuffer_{};
|
|
unsigned indexStart_{};
|
|
unsigned indexCount_{};
|
|
HashMap<unsigned, PODVector<BoneWeightAssignment> > boneWeights_;
|
|
PODVector<unsigned> boneMapping_;
|
|
};
|