summaryrefslogtreecommitdiff
path: root/src/simulation
diff options
context:
space:
mode:
Diffstat (limited to 'src/simulation')
-rw-r--r--src/simulation/Simulation.cpp118
-rw-r--r--src/simulation/Simulation.h2
-rw-r--r--src/simulation/elements/RBDM.cpp4
-rw-r--r--src/simulation/tools/SolidTool.cpp26
4 files changed, 122 insertions, 28 deletions
diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp
index 375d918..f0bd48c 100644
--- a/src/simulation/Simulation.cpp
+++ b/src/simulation/Simulation.cpp
@@ -2673,6 +2673,37 @@ void Simulation::unlink_solid(int i)
parts[i].sld = 0;
}
+int Simulation::link_solid(int i, int sld)
+{
+ Solid *s = solids + sld;
+
+ if(parts[i].sld)
+ return 0;
+
+ parts[i].sld = sld + 1;
+ if(s->first == -1) {
+ s->vx = s->vy = s->vrot = 0.0f;
+ s->cx = s->cdx = parts[i].x;
+ s->cy = s->cdy = parts[i].y;
+ s->ax = s->ay = s->arot = s->arad = 0.0f;
+ s->an = 0;
+ s->bf = 0;
+ s->bpx[0] = -10000;
+ s->bpx[1] = 10000;
+ s->bpy[2] = -10000;
+ s->bpy[3] = 10000;
+ s->first = i;
+ }
+
+ parts[i].snext = -1;
+ parts[i].sprev = s->last;
+ if(s->last != -1)
+ parts[s->last].snext = i;
+ s->last = i;
+
+ return 1;
+}
+
void Simulation::kill_part(int i)//kills particle number i
{
int x = (int)(parts[i].x+0.5f);
@@ -4754,9 +4785,49 @@ int Simulation::GetParticleType(std::string type)
return -1;
}
+void Simulation::solid_respawn(int i, int pp, int dx, int dy)
+{
+ int nx = (int)(parts[pp].x + 0.5f), ny = (int)(parts[pp].y + 0.5f);
+ int nc, t, pq;
+
+ if(pmap[ny+dy][nx+dx])
+ return;
+
+ nc = 1;
+ t = pmap[ny+2*dy][nx+2*dx]; if(t && parts[t >> 8].sld == i+1) nc ++;
+ t = pmap[ny+dy+dx][nx+dx+dy]; if(t && parts[t >> 8].sld == i+1) nc ++;
+ t = pmap[ny+dy-dx][nx+dx-dy]; if(t && parts[t >> 8].sld == i+1) nc ++;
+ if(nc < 3)
+ return;
+
+ pq = create_part(-1, nx+dx, ny+dy, parts[pp].type);
+ if(pq < 0)
+ return;
+
+ parts[pq].life = parts[pp].life;
+ parts[pq].ctype = parts[pp].ctype;
+ parts[pq].flags = parts[pp].flags;
+ parts[pq].temp = parts[pp].temp;
+ parts[pq].tmp = parts[pp].tmp;
+ parts[pq].tmp2 = parts[pp].tmp2;
+ parts[pq].dcolour = parts[pp].dcolour;
+ if(pmap[ny+2*dy][nx+2*dx]) {
+ parts[pq].x = (parts[pp].x + parts[pmap[ny+2*dy][nx+2*dx] >> 8].x) * 0.5f;
+ parts[pq].y = (parts[pp].y + parts[pmap[ny+2*dy][nx+2*dx] >> 8].y) * 0.5f;
+ parts[pq].vx = (parts[pp].vx + parts[pmap[ny+2*dy][nx+2*dx] >> 8].vx) * 0.5f;
+ parts[pq].vy = (parts[pp].vy + parts[pmap[ny+2*dy][nx+2*dx] >> 8].vy) * 0.5f;
+ } else {
+ parts[pq].x = (parts[pmap[ny+dy+dx][nx+dx+dy] >> 8].x + parts[pmap[ny+dy-dx][nx+dx-dy] >> 8].x) * 0.5f;
+ parts[pq].y = (parts[pmap[ny+dy+dx][nx+dx+dy] >> 8].y + parts[pmap[ny+dy-dx][nx+dx-dy] >> 8].y) * 0.5f;
+ parts[pq].vx = (parts[pmap[ny+dy+dx][nx+dx+dy] >> 8].vx + parts[pmap[ny+dy-dx][nx+dx-dy] >> 8].vx) * 0.5f;
+ parts[pq].vy = (parts[pmap[ny+dy+dx][nx+dx+dy] >> 8].vy + parts[pmap[ny+dy-dx][nx+dx-dy] >> 8].vy) * 0.5f;
+ }
+ link_solid(pq, i);
+}
+
void Simulation::update_solids()
{
- int i, pp, nc, bb, bd, nx, ny;
+ int i, pp, pq, nc, bb, bd, nx, ny;
float adx, ady, mmx, mmy, dd, ee, rmx, rmy, vx, vy, av;
float vrot, cvrot, svrot;
Solid *sld;
@@ -4770,15 +4841,60 @@ void Simulation::update_solids()
cvrot = cosf(sld->vrot) - 1.0f;
svrot = sinf(sld->vrot);
for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
+ nx = (int)(parts[pp].x + 0.5f);
+ ny = (int)(parts[pp].y + 0.5f);
+ if((pmap[ny][nx] >> 8) == pp)
+ pmap[ny][nx] = 0;
adx = parts[pp].x - sld->cdx;
ady = parts[pp].y - sld->cdy;
vx = sld->vx + adx*cvrot + ady*svrot;
vy = sld->vy + ady*cvrot - adx*svrot;
parts[pp].x += vx;
parts[pp].y += vy;
+ nx = (int)(parts[pp].x + 0.5f);
+ ny = (int)(parts[pp].y + 0.5f);
+ if(nx >= CELL && nx < XRES-CELL && ny >= CELL && ny < YRES-CELL) {
+ pmap[ny][nx] = (pp << 8) | parts[pp].type;
+ } else {
+ unlink_solid(pp);
+ if(elementCount[parts[pp].type])
+ elementCount[parts[pp].type]--;
+ parts[pp].type = PT_NONE;
+ parts[pp].life = pfree;
+ pfree = pp;
+ }
+ }
+ for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
+ nx = (int)(parts[pp].x + 0.5f);
+ ny = (int)(parts[pp].y + 0.5f);
+ if((pmap[ny][nx] >> 8) != pp) {
+ if(!pmap[ny][nx-1] || parts[pmap[ny][nx-1] >> 8].sld != i+1) continue;
+ if(!pmap[ny][nx+1] || parts[pmap[ny][nx+1] >> 8].sld != i+1) continue;
+ if(!pmap[ny-1][nx] || parts[pmap[ny-1][nx] >> 8].sld != i+1) continue;
+ if(!pmap[ny+1][nx] || parts[pmap[ny+1][nx] >> 8].sld != i+1) continue;
+ pq = pmap[ny][nx] >> 8;
+ if(fabs(parts[pq].vx) < fabs(parts[pp].vx))
+ parts[pq].vx = parts[pp].vx;
+ if(fabs(parts[pq].vy) < fabs(parts[pp].vy))
+ parts[pq].vy = parts[pp].vy;
+ unlink_solid(pp);
+ if(elementCount[parts[pp].type])
+ elementCount[parts[pp].type]--;
+ parts[pp].type = PT_NONE;
+ parts[pp].life = pfree;
+ pfree = pp;
+ } else {
+ solid_respawn(i, pp, -1, 0);
+ solid_respawn(i, pp, 1, 0);
+ solid_respawn(i, pp, 0, -1);
+ solid_respawn(i, pp, 0, 1);
+ }
}
}
+ if(sld->first == -1)
+ continue;
+
for(pp=sld->first; pp!=-1; pp=parts[pp].snext) {
nx = (int)(parts[pp].x + 0.5f);
ny = (int)(parts[pp].y + 0.5f);
diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h
index 7b0ee91..c671e5a 100644
--- a/src/simulation/Simulation.h
+++ b/src/simulation/Simulation.h
@@ -152,6 +152,7 @@ public:
TPT_NO_INLINE int create_part(int p, int x, int y, int t);
TPT_NO_INLINE void delete_part(int x, int y);
void unlink_solid(int part);
+ int link_solid(int part, int sld);
void get_sign_pos(int i, int *x0, int *y0, int *w, int *h);
TPT_NO_INLINE int is_wire(int x, int y);
TPT_NO_INLINE int is_wire_off(int x, int y);
@@ -159,6 +160,7 @@ public:
TPT_NO_INLINE int parts_avg(int ci, int ni, int t);
void create_arc(int sx, int sy, int dx, int dy, int midpoints, int variance, int type, int flags);
int nearest_part(int ci, int t, int max_d);
+ void solid_respawn(int i, int pp, int dx, int dy);
void update_particles_i(int start, int inc);
void update_particles();
void update_solids();
diff --git a/src/simulation/elements/RBDM.cpp b/src/simulation/elements/RBDM.cpp
index 24ada3f..15d36f9 100644
--- a/src/simulation/elements/RBDM.cpp
+++ b/src/simulation/elements/RBDM.cpp
@@ -12,9 +12,9 @@ Element_RBDM::Element_RBDM()
Advection = 0.0f;
AirDrag = 0.00f * CFDS;
AirLoss = 0.90f;
- Loss = 0.99f;
+ Loss = 1.00f;
Collision = 0.0f;
- Gravity = 0.1f;
+ Gravity = 0.12f;
Diffusion = 0.00f;
HotAir = 0.000f * CFDS;
Falldown = 0;
diff --git a/src/simulation/tools/SolidTool.cpp b/src/simulation/tools/SolidTool.cpp
index 1cbfa46..f8fdf2a 100644
--- a/src/simulation/tools/SolidTool.cpp
+++ b/src/simulation/tools/SolidTool.cpp
@@ -37,31 +37,7 @@ int Tool_Solid::Perform(Simulation * sim, Particle * cpart, int x, int y, float
return 0;
LastSolid = solid_index;
- Solid *sld = sim->solids + solid_index;
-
- cpart->sld = solid_index + 1;
- if(sld->first == -1) {
- sld->vx = sld->vy = sld->vrot = 0.0f;
- sld->cx = x;
- sld->cy = y;
- sld->cdx = x;
- sld->cdy = y;
- sld->ax = sld->ay = sld->arot = sld->arad = 0.0f;
- sld->an = 0;
- sld->bf = 0;
- sld->bpx[0] = -10000;
- sld->bpx[1] = 10000;
- sld->bpy[2] = -10000;
- sld->bpy[3] = 10000;
- sld->first = cpart - sim->parts;
- }
-
- cpart->snext = -1;
- cpart->sprev = sld->last;
- if(sld->last != -1)
- sim->parts[sld->last].snext = cpart - sim->parts;
- sld->last = cpart - sim->parts;
- return 1;
+ return sim->link_solid(cpart - sim->parts, solid_index);
}
Tool_Solid::~Tool_Solid() {}