OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
meshobjects.cpp
Go to the documentation of this file.
1#include "meshobjects.h"
2
3#include <Tempest/Log>
4
9
10#include "visualobjects.h"
11
13 :parent(parent) {
14 }
15
18
19MeshObjects::Item MeshObjects::implGet(const StaticMesh &mesh, const StaticMesh::SubMesh& s,
20 int32_t texVar, int32_t teethTex, int32_t bodyColor,
21 bool staticDraw) {
22 Material mat = s.material;
23 if(teethTex!=0 || bodyColor!=0 || texVar!=0){
24 if(s.texName=="HUM_TEETH_V0.TGA"){
25 mat.tex=solveTex(s.material.tex,s.texName,teethTex,bodyColor);
26 }
27 else if(s.texName=="HUM_MOUTH_V0.TGA"){
28 mat.tex=solveTex(s.material.tex,s.texName,teethTex,bodyColor);
29 }
30 else if(s.texName.find_first_of("VC")!=std::string::npos){
31 mat.tex=solveTex(s.material.tex,s.texName,texVar,bodyColor);
32 }
33 }
34
35 if(mat.tex==nullptr) {
36 if(!s.texName.empty())
37 Tempest::Log::e("texture not found: \"",s.texName,"\"");
38 return MeshObjects::Item();
39 }
40 return parent.get(mesh,mat,s.iboOffset,s.iboLength,staticDraw);
41 }
42
43const Tempest::Texture2d *MeshObjects::solveTex(const Tempest::Texture2d *def, std::string_view format, int32_t v, int32_t c) {
44 if(format.find_first_of("VC")!=std::string::npos){
45 auto ntex = Resources::loadTexture(format,v,c);
46 if(ntex!=nullptr)
47 return ntex;
48 }
49 return def;
50 }
51
53 skeleton = sk;
54 if(proto!=nullptr && skeleton!=nullptr)
55 binder=Resources::bindMesh(*proto,*skeleton);
56 }
57
58void MeshObjects::Mesh::setPose(const Tempest::Matrix4x4& obj, const Pose &p) {
59 if(anim!=nullptr)
60 anim->set(p.transform());
61 implSetObjMatrix(obj,p.transform());
62 }
63
65 for(size_t i=0;i<subCount;++i)
66 sub[i].setAsGhost(g);
67 }
68
70 for(size_t i=0;i<subCount;++i)
71 sub[i].setFatness(f);
72 }
73
74void MeshObjects::Mesh::setWind(zenkit::AnimationType m, float intensity) {
75 for(size_t i=0;i<subCount;++i)
76 sub[i].setWind(m,intensity);
77 }
78
79void MeshObjects::Mesh::startMMAnim(std::string_view anim, float intensity, uint64_t timeUntil) {
80 for(size_t i=0;i<subCount;++i)
81 sub[i].startMMAnim(anim,intensity,timeUntil);
82 }
83
85 if(subCount==0)
86 return Bounds();
87 auto b = node(0).bounds();
88 for(size_t i=1; i<subCount; ++i)
89 b.assign(b,sub[i].bounds());
90 return b;
91 }
92
94 if(auto p = proto)
95 return Resources::loadEmiterMesh(p->fname);
96 return nullptr;
97 }
98
100 *this = std::move(other);
101 }
102
105
106MeshObjects::Mesh::Mesh(MeshObjects& owner, const StaticMesh& mesh, int32_t version, bool staticDraw) {
107 sub.reset(new Item[mesh.sub.size()]);
108 subCount = 0;
109 for(size_t i=0;i<mesh.sub.size();++i) {
110 // NOTE: light dragon hunter armour
111 if(mesh.sub[i].texName.find_first_of("VC")==std::string::npos && version!=0)
112 continue;
113 Item it = owner.implGet(mesh,mesh.sub[i],0,0,version,staticDraw);
114 if(it.isEmpty())
115 continue;
116 sub[subCount] = std::move(it);
117 ++subCount;
118 }
119 }
120
122 int32_t texVar, int32_t teethTex, int32_t bodyColor) {
123 sub.reset(new Item[mesh.sub.size()]);
124 subCount = 0;
125 for(size_t i=0;i<mesh.sub.size();++i){
126 Item it = owner.implGet(mesh,mesh.sub[i],texVar,teethTex,bodyColor,false);
127 if(it.isEmpty())
128 continue;
129 sub[subCount] = std::move(it);
130 ++subCount;
131 }
132 }
133
135 int32_t texVar, int32_t teethTex, int32_t bodyColor, bool staticDraw)
136 :proto(&mesh) {
137 const size_t skinnedCount = mesh.skinedNodesCount();
138 sub.reset(new Item[mesh.submeshId.size()+skinnedCount]);
139 subCount = 0;
140
141 for(auto& m:mesh.submeshId) {
142 auto& att = mesh.attach[m.id];
143 auto& sub = att.sub[m.subId];
144 Item it = owner.implGet(att,sub,texVar,teethTex,bodyColor,staticDraw);
145 if(it.isEmpty())
146 continue;
147 this->sub[subCount] = std::move(it);
148 subCount++;
149 }
150
151 size_t bonesCount = 0;
152 for(size_t i=0; i<mesh.skined.size(); ++i)
153 bonesCount = std::max(bonesCount,mesh.skined[i].bonesCount);
154
155 if(bonesCount>0)
156 anim.reset(new InstanceStorage::Id(owner.parent.alloc(bonesCount*sizeof(Tempest::Matrix4x4))));
157
158 for(size_t i=0; i<mesh.skined.size(); ++i) {
159 auto& skin = mesh.skined[i];
160 for(auto& m:skin.sub) {
161 Material mat = m.material;
162 mat.tex=owner.solveTex(mat.tex,m.texName,texVar,bodyColor);
163 if(mat.tex!=nullptr) {
164 sub[subCount] = owner.parent.get(skin,mat,m.iboOffset,m.iboSize,*anim);
165 ++subCount;
166 } else {
167 if(!m.texName.empty())
168 Tempest::Log::e("texture not found: \"",m.texName,"\"");
169 }
170 }
171 }
172
173 if(mesh.morph.size()>0)
174 startMMAnim(mesh.morph[0].name,1,uint64_t(-1));
175 }
176
178 std::swap(sub, other.sub);
179 std::swap(subCount, other.subCount);
180 std::swap(anim, other.anim);
181 std::swap(proto, other.proto);
182 std::swap(skeleton, other.skeleton);
183 std::swap(binder, other.binder);
184 return *this;
185 }
186
187void MeshObjects::Mesh::setObjMatrix(const Tempest::Matrix4x4 &mt) {
188 implSetObjMatrix(mt,skeleton==nullptr ? nullptr : skeleton->tr.data());
189 }
190
191void MeshObjects::Mesh::implSetObjMatrix(const Tempest::Matrix4x4& mt, const Tempest::Matrix4x4* tr) {
192 const size_t binds = (binder==nullptr ? 0 : binder->bind.size());
193 for(size_t i=0; i<binds; ++i) {
194 auto id = binder->bind[i];
195 sub[i].setObjMatrix(tr[id]);
196 }
197 for(size_t i=binds; i<subCount; ++i)
198 sub[i].setObjMatrix(mt);
199 }
200
202 return it->bounds();
203 }
204
206 return it->material();
207 }
208
209Tempest::Matrix4x4 MeshObjects::Node::position() const {
210 return it->position();
211 }
212
214 return it->mesh();
215 }
216
217std::pair<uint32_t, uint32_t> MeshObjects::Node::meshSlice() const {
218 return it->meshSlice();
219 }
const Tempest::Texture2d * tex
Definition material.h:28
void setPose(const Tempest::Matrix4x4 &obj, const Pose &p)
Mesh & operator=(Mesh &&other)
void setAsGhost(bool g)
void setWind(zenkit::AnimationType m, float intensity)
void setFatness(float f)
void startMMAnim(std::string_view anim, float intensity, uint64_t timeUntil)
void setObjMatrix(const Tempest::Matrix4x4 &mt)
void setSkeleton(const Skeleton *sk)
const PfxEmitterMesh * toMeshEmitter() const
Bounds bounds() const
Tempest::Matrix4x4 position() const
const Material & material() const
const Bounds & bounds() const
std::pair< uint32_t, uint32_t > meshSlice() const
const StaticMesh * mesh() const
MeshObjects(VisualObjects &parent)
Definition pose.h:16
const Tempest::Matrix4x4 * transform() const
Definition pose.cpp:889
std::vector< AnimMesh > skined
Definition protomesh.h:77
std::vector< Attach > attach
Definition protomesh.h:82
std::vector< Morph > morph
Definition protomesh.h:78
size_t skinedNodesCount() const
std::vector< SubMeshId > submeshId
Definition protomesh.h:84
static const PfxEmitterMesh * loadEmiterMesh(std::string_view name)
static const Tempest::Texture2d * loadTexture(std::string_view name, bool forceMips=false)
static const AttachBinder * bindMesh(const ProtoMesh &anim, const Skeleton &s)
std::vector< SubMesh > sub
Definition staticmesh.h:55
bool isEmpty() const
Item get(const StaticMesh &mesh, const Material &mat, size_t iboOffset, size_t iboLength, bool staticDraw)
InstanceStorage::Id alloc(size_t size)
std::string texName
Definition staticmesh.h:27