File include/particle.h changed (mode: 100644) (index 85cae5e..d3a7c1a) |
... |
... |
class Particle { |
28 |
28 |
double dragModel = 0.525; // A cube. |
double dragModel = 0.525; // A cube. |
29 |
29 |
double age = 0.0; |
double age = 0.0; |
30 |
30 |
double maxAge = DBL_MAX; |
double maxAge = DBL_MAX; |
|
31 |
|
double damage = 0.0; // Damage dealt on impact. User should test collisions if nonzero. |
|
32 |
|
void *userptr = nullptr; // Not loaded from JSON. User can set this. |
31 |
33 |
}; |
}; |
32 |
34 |
|
|
33 |
35 |
class ParticleTemplate { |
class ParticleTemplate { |
|
... |
... |
class ParticleTemplate { |
40 |
42 |
double startMass = 1.0; |
double startMass = 1.0; |
41 |
43 |
double endMass = 1.0; |
double endMass = 1.0; |
42 |
44 |
double maxAge = DBL_MAX; |
double maxAge = DBL_MAX; |
|
45 |
|
double damage = 0.0; |
43 |
46 |
ParticleTemplate( const std::string &text = "" ); |
ParticleTemplate( const std::string &text = "" ); |
44 |
47 |
}; |
}; |
45 |
48 |
|
|
|
... |
... |
class ParticleServer { |
60 |
63 |
double endScale, |
double endScale, |
61 |
64 |
double startMass, |
double startMass, |
62 |
65 |
double endMass, |
double endMass, |
63 |
|
double maxAge ); |
|
|
66 |
|
double maxAge, |
|
67 |
|
double damage, |
|
68 |
|
void *userptr = nullptr ); |
64 |
69 |
void addOmniBurst( |
void addOmniBurst( |
65 |
70 |
size_t num, |
size_t num, |
66 |
71 |
double vel, |
double vel, |
|
... |
... |
class ParticleServer { |
69 |
74 |
double endScale, |
double endScale, |
70 |
75 |
double startMass, |
double startMass, |
71 |
76 |
double endMass, |
double endMass, |
72 |
|
double maxAge ); |
|
|
77 |
|
double maxAge, |
|
78 |
|
double damage, |
|
79 |
|
void *userptr = nullptr ); |
73 |
80 |
void simulate( double d ); |
void simulate( double d ); |
74 |
81 |
void draw( fgl::Texture &tex, linalg::mat<double,4,4> viewMat, linalg::mat<double,4,4> projMat, bool shadowPass = false ); |
void draw( fgl::Texture &tex, linalg::mat<double,4,4> viewMat, linalg::mat<double,4,4> projMat, bool shadowPass = false ); |
75 |
82 |
ParticleServer(); |
ParticleServer(); |
|
... |
... |
ParticleTemplate::ParticleTemplate( const std::string &text ){ |
122 |
129 |
if( info["maxAge"] ){ |
if( info["maxAge"] ){ |
123 |
130 |
maxAge = info["maxAge"].getDouble(); |
maxAge = info["maxAge"].getDouble(); |
124 |
131 |
} |
} |
|
132 |
|
if( info["damage"] ){ |
|
133 |
|
damage = info["damage"].getDouble(); |
|
134 |
|
} |
125 |
135 |
|
|
126 |
136 |
jsonFreeDocument( &allocatedDocument ); |
jsonFreeDocument( &allocatedDocument ); |
127 |
137 |
} |
} |
|
... |
... |
void ParticleServer::addParticle( |
143 |
153 |
double endScale, |
double endScale, |
144 |
154 |
double startMass, |
double startMass, |
145 |
155 |
double endMass, |
double endMass, |
146 |
|
double maxAge ){ |
|
|
156 |
|
double maxAge, |
|
157 |
|
double damage, |
|
158 |
|
void *userptr ){ |
147 |
159 |
Particle part{}; |
Particle part{}; |
148 |
160 |
part.tvel = vel; |
part.tvel = vel; |
149 |
161 |
part.translation = pos; |
part.translation = pos; |
|
... |
... |
void ParticleServer::addParticle( |
152 |
164 |
part.mvel = (endMass - startMass) / maxAge; |
part.mvel = (endMass - startMass) / maxAge; |
153 |
165 |
part.mass = startMass; |
part.mass = startMass; |
154 |
166 |
part.maxAge = maxAge; |
part.maxAge = maxAge; |
|
167 |
|
part.damage = damage; |
|
168 |
|
part.userptr = userptr; |
155 |
169 |
particles.push_back( part ); |
particles.push_back( part ); |
156 |
170 |
} |
} |
157 |
171 |
|
|
|
... |
... |
void ParticleServer::addOmniBurst( |
163 |
177 |
double endScale, |
double endScale, |
164 |
178 |
double startMass, |
double startMass, |
165 |
179 |
double endMass, |
double endMass, |
166 |
|
double maxAge ){ |
|
|
180 |
|
double maxAge, |
|
181 |
|
double damage, |
|
182 |
|
void *userptr ){ |
167 |
183 |
double svel = (endScale - startScale) / maxAge; |
double svel = (endScale - startScale) / maxAge; |
168 |
184 |
double mvel = (endMass - startMass) / maxAge; |
double mvel = (endMass - startMass) / maxAge; |
169 |
185 |
for( size_t i = 0; i < num; ++i ){ |
for( size_t i = 0; i < num; ++i ){ |
|
... |
... |
void ParticleServer::addOmniBurst( |
178 |
194 |
part.mvel = mvel; |
part.mvel = mvel; |
179 |
195 |
part.mass = startMass; |
part.mass = startMass; |
180 |
196 |
part.maxAge = maxAge; |
part.maxAge = maxAge; |
|
197 |
|
part.damage = damage; |
|
198 |
|
part.userptr = userptr; |
181 |
199 |
particles.push_back( part ); |
particles.push_back( part ); |
182 |
200 |
} |
} |
183 |
201 |
} |
} |
File src/fdungeon.cpp changed (mode: 100644) (index c0b2e91..05186db) |
... |
... |
class Dungeon { |
502 |
502 |
void moveMouse( double x, double y ); |
void moveMouse( double x, double y ); |
503 |
503 |
void prepareLightBuffers( double d ); |
void prepareLightBuffers( double d ); |
504 |
504 |
void simulateWater( float wscale, double d ); |
void simulateWater( float wscale, double d ); |
505 |
|
void simulate( double maxDraw, double d ); |
|
|
505 |
|
void simulate( double maxDraw, double d, std::string defenseSkill = "def" ); |
506 |
506 |
void updateMonoCamera(); |
void updateMonoCamera(); |
507 |
507 |
void updateStereoCamera(); |
void updateStereoCamera(); |
508 |
508 |
fgl::Pipeline useDungeonPipeline( bool skinPass, bool shadowPass ); |
fgl::Pipeline useDungeonPipeline( bool skinPass, bool shadowPass ); |
|
... |
... |
Agent *Dungeon::rayImpact( Agent *a, std::pair<linalg::vec<double,3>,linalg::vec |
3229 |
3229 |
defaultBlood.num, defaultBlood.vel, |
defaultBlood.num, defaultBlood.vel, |
3230 |
3230 |
{hit.getX(), hit.getY(), hit.getZ()}, |
{hit.getX(), hit.getY(), hit.getZ()}, |
3231 |
3231 |
defaultBlood.startScale, defaultBlood.endScale, |
defaultBlood.startScale, defaultBlood.endScale, |
3232 |
|
defaultBlood.startMass, defaultBlood.endMass, defaultBlood.maxAge ); |
|
|
3232 |
|
defaultBlood.startMass, defaultBlood.endMass, defaultBlood.maxAge, |
|
3233 |
|
defaultBlood.damage, (void*)&defaultAgent ); |
3233 |
3234 |
} |
} |
3234 |
3235 |
}else{ |
}else{ |
3235 |
3236 |
// No avatar = default impact |
// No avatar = default impact |
|
... |
... |
Agent *Dungeon::rayImpact( Agent *a, std::pair<linalg::vec<double,3>,linalg::vec |
3239 |
3240 |
defaultImpact.num, defaultImpact.vel, |
defaultImpact.num, defaultImpact.vel, |
3240 |
3241 |
{hit.getX(), hit.getY(), hit.getZ()}, |
{hit.getX(), hit.getY(), hit.getZ()}, |
3241 |
3242 |
defaultImpact.startScale, defaultImpact.endScale, |
defaultImpact.startScale, defaultImpact.endScale, |
3242 |
|
defaultImpact.startMass, defaultImpact.endMass, defaultImpact.maxAge ); |
|
|
3243 |
|
defaultImpact.startMass, defaultImpact.endMass, defaultImpact.maxAge, |
|
3244 |
|
defaultImpact.damage, (void*)&defaultAgent ); |
3243 |
3245 |
} |
} |
3244 |
3246 |
} |
} |
3245 |
3247 |
}else{ |
}else{ |
|
... |
... |
Agent *Dungeon::rayImpact( Agent *a, std::pair<linalg::vec<double,3>,linalg::vec |
3254 |
3256 |
defaultImpact.num, defaultImpact.vel, |
defaultImpact.num, defaultImpact.vel, |
3255 |
3257 |
{hit.getX(), hit.getY(), hit.getZ()}, |
{hit.getX(), hit.getY(), hit.getZ()}, |
3256 |
3258 |
defaultImpact.startScale, defaultImpact.endScale, |
defaultImpact.startScale, defaultImpact.endScale, |
3257 |
|
defaultImpact.startMass, defaultImpact.endMass, defaultImpact.maxAge ); |
|
|
3259 |
|
defaultImpact.startMass, defaultImpact.endMass, defaultImpact.maxAge, |
|
3260 |
|
defaultImpact.damage, (void*)&defaultAgent ); |
3258 |
3261 |
} |
} |
3259 |
3262 |
} |
} |
3260 |
3263 |
if( rb->getInvMass() != 0.0 ){ |
if( rb->getInvMass() != 0.0 ){ |
|
... |
... |
std::pair<bool,Agent*> Dungeon::agentFireWeapon( Agent *a, std::string weapon, s |
3352 |
3355 |
part.mvel = mvel; |
part.mvel = mvel; |
3353 |
3356 |
part.mass = startMass; |
part.mass = startMass; |
3354 |
3357 |
part.maxAge = maxAge; |
part.maxAge = maxAge; |
|
3358 |
|
part.damage = weap.particleFire.damage; |
|
3359 |
|
part.userptr = (void*)a; |
3355 |
3360 |
ps_it->second.particles.push_back(part); |
ps_it->second.particles.push_back(part); |
3356 |
3361 |
} |
} |
3357 |
3362 |
} |
} |
|
... |
... |
template<class T> linalg::mat<T,4,4> ortho( |
3770 |
3775 |
} |
} |
3771 |
3776 |
|
|
3772 |
3777 |
// Physics, shadow, and camera position handling. |
// Physics, shadow, and camera position handling. |
3773 |
|
void Dungeon::simulate( double maxDraw, double d ){ |
|
|
3778 |
|
void Dungeon::simulate( double maxDraw, double d, std::string defenseSkill ){ |
3774 |
3779 |
if( !dynamicsWorld ) |
if( !dynamicsWorld ) |
3775 |
3780 |
return; |
return; |
3776 |
3781 |
simulateWater( 16.0f, d ); |
simulateWater( 16.0f, d ); |
|
... |
... |
void Dungeon::simulate( double maxDraw, double d ){ |
3996 |
4001 |
} |
} |
3997 |
4002 |
|
|
3998 |
4003 |
// Simulate particles. |
// Simulate particles. |
3999 |
|
for( auto &ps : particleServers ) ps.second.simulate( d ); |
|
|
4004 |
|
for( auto &ps : particleServers ){ |
|
4005 |
|
ps.second.simulate( d ); |
|
4006 |
|
// Simulate collisions and damage for damaging particles. |
|
4007 |
|
for( auto &p : ps.second.particles ){ |
|
4008 |
|
if( p.damage != 0.0 ){ |
|
4009 |
|
// Cast a ray from the particle's previous position to its current position. |
|
4010 |
|
// Cap mass to 10 kg because it may be set very high in order to cheat drag. |
|
4011 |
|
// Ultra-high mass = ultra-high impact = objects clip through walls |
|
4012 |
|
auto tprev = p.translation - p.tvel * d; |
|
4013 |
|
if(rayImpact((Agent*)p.userptr, {tprev, p.translation}, |
|
4014 |
|
linalg::length(p.tvel) * std::min(p.mass, 10.0), p.damage, defenseSkill)){ |
|
4015 |
|
p.age = DBL_MAX; |
|
4016 |
|
} |
|
4017 |
|
} |
|
4018 |
|
} |
|
4019 |
|
} |
4000 |
4020 |
|
|
4001 |
4021 |
// Configure the shadow map. |
// Configure the shadow map. |
4002 |
4022 |
//shadowViewMat = linalg::pose_matrix( fgl::eulerToQuat( -0.7, 0.0, 0.0 ), { 0.0, 10.0, 20.0 } ); |
//shadowViewMat = linalg::pose_matrix( fgl::eulerToQuat( -0.7, 0.0, 0.0 ), { 0.0, 10.0, 20.0 } ); |