OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
pfxemitter.cpp
Go to the documentation of this file.
1#include "pfxemitter.h"
2
3#include <Tempest/Log>
4
8
9#include "world/world.h"
10#include "utils/fileext.h"
11#include "gothic.h"
12
13using namespace Tempest;
14
16 :bucket(&b), id(id) {
17 }
18
19PfxEmitter::PfxEmitter(World& world, std::string_view name)
20 :PfxEmitter(world,Gothic::inst().loadParticleFx(name)) {
21 }
22
24 :PfxEmitter(world.view()->pfxGroup,decl) {
25 }
26
28 if(decl==nullptr || (decl->visMaterial.tex==nullptr && !decl->hasTrails()))
29 return;
30 std::lock_guard<std::recursive_mutex> guard(owner.sync);
31 bucket = &owner.getBucket(*decl);
32 id = bucket->allocEmitter();
33 if(decl->shpMesh!=nullptr && decl->shpMeshRender)
34 shpMesh = owner.world.addView(decl->shpMesh_S,0,0,0);
35 }
36
37PfxEmitter::PfxEmitter(World& world, const zenkit::VirtualObject& vob) {
38 auto& owner = world.view()->pfxGroup;
39 if(FileExt::hasExt(vob.visual->name,"PFX")) {
40 auto decl = Gothic::inst().loadParticleFx(vob.visual->name);
41 if(decl==nullptr || decl->visMaterial.tex==nullptr)
42 return;
43 std::lock_guard<std::recursive_mutex> guard(owner.sync);
44 bucket = &owner.getBucket(*decl);
45 id = bucket->allocEmitter();
46 }
47 else if(auto decal = dynamic_cast<const zenkit::VisualDecal*>(vob.visual.get())) {
48 Material mat(*decal);
49 std::lock_guard<std::recursive_mutex> guard(owner.sync);
50 bucket = &owner.getBucket(mat,vob);
51 id = bucket->allocEmitter();
52 }
53 }
54
56 if(bucket!=nullptr) {
57 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
58 bucket->freeEmitter(id);
59 }
60 }
61
63 :bucket(b.bucket), id(b.id), zone(std::move(b.zone)) {
64 b.bucket = nullptr;
65 }
66
68 std::swap(bucket,b.bucket);
69 std::swap(id, b.id);
70 std::swap(zone, b.zone);
71 return *this;
72 }
73
74void PfxEmitter::setPosition(float x, float y, float z) {
75 setPosition(Vec3(x,y,z));
76 }
77
78void PfxEmitter::setPosition(const Vec3& pos) {
79 if(bucket==nullptr)
80 return;
81 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
82 auto& v = bucket->get(id);
83 v.pos = pos;
84 zone.setPosition(pos);
85
86 if(v.next!=nullptr)
87 v.next->setPosition(pos);
88 if(v.block==size_t(-1))
89 return; // no backup memory
90 auto& p = bucket->getBlock(*this);
91 p.pos = pos;
92 }
93
94void PfxEmitter::setTarget(const Npc* tg) {
95 if(bucket==nullptr)
96 return;
97 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
98 auto& v = bucket->get(id);
99 v.targetNpc = tg;
100 }
101
102void PfxEmitter::setDirection(const Matrix4x4& d) {
103 if(bucket==nullptr)
104 return;
105 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
106 auto& v = bucket->get(id);
107 v.direction[0] = Vec3(d.at(0,0),d.at(0,1),d.at(0,2));
108 v.direction[1] = Vec3(d.at(1,0),d.at(1,1),d.at(1,2));
109 v.direction[2] = Vec3(d.at(2,0),d.at(2,1),d.at(2,2));
110
111 if(v.next!=nullptr)
112 v.next->setDirection(d);
113 }
114
115void PfxEmitter::setActive(bool act) {
116 if(bucket==nullptr)
117 return;
118 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
119 auto& v = bucket->get(id);
120 auto state = (act ? PfxBucket::S_Active : PfxBucket::S_Inactive);
121 if(v.st==state)
122 return;
123 v.st = state;
124 if(v.next!=nullptr)
125 v.next->setActive(act);
126 if(act==true)
127 v.waitforNext = bucket->decl.ppsCreateEmDelay;
128 }
129
131 if(bucket==nullptr)
132 return false;
133 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
134 auto& v = bucket->get(id);
135 return v.st==PfxBucket::S_Active;
136 }
137
138void PfxEmitter::setLooped(bool loop) {
139 if(bucket==nullptr)
140 return;
141 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
142 auto& v = bucket->get(id);
143 v.isLoop = loop;
144 if(v.next!=nullptr)
145 v.next->setLooped(loop);
146 }
147
148void PfxEmitter::setMesh(const MeshObjects::Mesh* mesh, const Pose* pose) {
149 const PfxEmitterMesh* m = (mesh!=nullptr) ? mesh->toMeshEmitter() : nullptr;
150
151 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
152 auto& v = bucket->get(id);
153 v.mesh = m;
154 v.pose = pose;
155 if(v.next!=nullptr)
156 v.next->setMesh(mesh,pose);
157 }
158
159void PfxEmitter::setPhysicsEnable(World& p, std::function<void (Npc&)> cb) {
160 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
161 auto& v = bucket->get(id);
162 zone = CollisionZone(p, v.pos, bucket->decl);
163 zone.setCallback(cb);
164 }
165
167 zone = CollisionZone();
168 }
169
171 if(bucket==nullptr)
172 return 0;
173 return bucket->decl.effectPrefferedTime();
174 }
175
177 if(bucket==nullptr)
178 return false;
179 std::lock_guard<std::recursive_mutex> guard(bucket->parent.sync);
180 auto& v = bucket->get(id);
181 if(v.block==size_t(-1))
182 return false;
183 auto& b = bucket->block[v.block];
184 return b.count>0;
185 }
186
187void PfxEmitter::setObjMatrix(const Matrix4x4 &mt) {
188 setPosition (mt.at(3,0),mt.at(3,1),mt.at(3,2));
189 setDirection(mt);
190 shpMesh.setObjMatrix(mt);
191 }
void setCallback(std::function< void(Npc &npc)> f)
void setPosition(const Tempest::Vec3 &p)
auto loadParticleFx(std::string_view name, bool relaxed=false) -> const ParticleFx *
Definition gothic.cpp:387
static Gothic & inst()
Definition gothic.cpp:249
const Tempest::Texture2d * tex
Definition material.h:28
void setObjMatrix(const Tempest::Matrix4x4 &mt)
const PfxEmitterMesh * toMeshEmitter() const
Definition npc.h:25
uint64_t ppsCreateEmDelay
Definition particlefx.h:64
Material visMaterial
Definition particlefx.h:98
uint64_t effectPrefferedTime() const
const PfxEmitterMesh * shpMesh
Definition particlefx.h:73
bool shpMeshRender
Definition particlefx.h:75
std::string shpMesh_S
Definition particlefx.h:74
bool hasTrails() const
void freeEmitter(size_t &id)
PfxObjects & parent
Definition pfxbucket.h:54
const ParticleFx & decl
Definition pfxbucket.h:53
ImplEmitter & get(size_t id)
Definition pfxbucket.h:66
size_t allocEmitter()
void setLooped(bool loop)
uint64_t effectPrefferedTime() const
void setObjMatrix(const Tempest::Matrix4x4 &mt)
bool isAlive() const
void setPhysicsEnable(World &physic, std::function< void(Npc &npc)> cb)
PfxEmitter()=default
bool isActive() const
void setMesh(const MeshObjects::Mesh *mesh, const Pose *pose)
void setPhysicsDisable()
void setActive(bool act)
void setDirection(const Tempest::Matrix4x4 &pos)
void setPosition(float x, float y, float z)
PfxEmitter & operator=(PfxEmitter &&b)
void setTarget(const Npc *tg)
Definition pose.h:16
MeshObjects::Mesh addView(std::string_view visual, int32_t headTex, int32_t teethTex, int32_t bodyColor)
Definition world.h:31
WorldView * view() const
Definition world.h:79
bool hasExt(std::string_view s, const char *extIn)
Definition fileext.h:8
Tempest::Vec3 pos
Definition pfxbucket.h:31
Tempest::Vec3 direction[3]
Definition pfxbucket.h:32
const Npc * targetNpc
Definition pfxbucket.h:35
const PfxEmitterMesh * mesh
Definition pfxbucket.h:37