renamed parallel_transport to shift_object, made it use shift_method, and made it correct for Lie movement

This commit is contained in:
Zeno Rogue 2022-12-17 11:35:28 +01:00
parent e1301e10bd
commit 4da63f57dc
4 changed files with 39 additions and 23 deletions

View File

@ -5042,11 +5042,11 @@ EX ld wall_radar(cell *c, transmatrix T, transmatrix LPe, ld max) {
ld step = max / 20;
ld fixed_yshift = 0;
for(int i=0; i<20; i++) {
T = parallel_transport(T, ori, ztangent(-step));
T = shift_object(T, ori, ztangent(-step), shift_method(false));
virtualRebase(c, T);
color_t col;
if(isWall3(c, col) || (WDIM == 2 && GDIM == 3 && tC0(T)[2] > cgi.FLOOR)) {
T = parallel_transport(T, ori, ztangent(step));
T = shift_object(T, ori, ztangent(step), shift_method(false));
step /= 2; i = 17;
if(step < 1e-3) break;
}
@ -5126,7 +5126,7 @@ EX void precise_mouseover() {
ld step = 0.2;
cell *c = centerover;
for(int i=0; i<100; i++) {
apply_parallel_transport(T, ori, ztangent(step));
apply_shift_object(T, ori, ztangent(step));
int pd = through_wall(c, T * C0);
if(pd != -1) {
color_t col;

View File

@ -1646,17 +1646,27 @@ EX eShiftMethod shift_method(bool automatic IS(false)) {
return smGeodesic;
}
EX transmatrix parallel_transport(const transmatrix Position, const transmatrix& ori, const hyperpoint direction) {
if(nonisotropic) return nisot::parallel_transport(Position, direction);
else if(gproduct) {
hyperpoint h = product::direct_exp(ori * direction);
return Position * rgpushxto0(h);
EX transmatrix shift_object(const transmatrix Position, const transmatrix& ori, const hyperpoint direction, eShiftMethod sm IS(shift_method(true))) {
switch(sm) {
case smGeodesic:
return nisot::parallel_transport(Position, direction);
case smLie:
return nisot::lie_transport(Position, direction);
case smProduct: {
hyperpoint h = product::direct_exp(ori * direction);
return Position * rgpushxto0(h);
}
case smIsometric: {
return Position * rgpushxto0(direct_exp(direction));
}
case smEmbedded: {
throw hr_exception("not implemented");
}
}
else return Position * rgpushxto0(direct_exp(direction));
}
EX void apply_parallel_transport(transmatrix& Position, const transmatrix orientation, const hyperpoint direction) {
Position = parallel_transport(Position, orientation, direction);
EX void apply_shift_object(transmatrix& Position, const transmatrix orientation, const hyperpoint direction, eShiftMethod sm IS(shift_method(true))) {
Position = shift_object(Position, orientation, direction, sm);
}
EX void rotate_object(transmatrix& Position, transmatrix& orientation, transmatrix R) {

View File

@ -2846,10 +2846,16 @@ EX namespace nisot {
EX transmatrix parallel_transport(const transmatrix Position, const hyperpoint direction) {
auto P = Position;
nisot::fixmatrix(P);
if(!geodesic_movement) return eupush(Position * translate(-direction) * inverse(Position) * C0, -1) * Position;
return parallel_transport_bare(P, direction);
}
EX transmatrix lie_transport(const transmatrix Position, const hyperpoint direction) {
transmatrix pshift = eupush( tC0(Position) );
transmatrix irot = iso_inverse(pshift) * Position;
hyperpoint tH = lie_exp(irot * direction);
return pshift * eupush(tH) * irot;
}
EX transmatrix spin_towards(const transmatrix Position, const hyperpoint goal, flagtype prec IS(pNORMAL)) {
hyperpoint at = tC0(Position);

View File

@ -1059,7 +1059,7 @@ void movePlayer(monster *m, int delta) {
playergoturn[cpid] = 0;
if(igo) { go = false; break; }
ld r = hypot_d(WDIM, avg_inertia);
apply_parallel_transport(nat.T, m->ori, lrspintox(avg_inertia) * xtangent(r * delta));
apply_shift_object(nat.T, m->ori, lrspintox(avg_inertia) * xtangent(r * delta));
if(WDIM == 3) rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
m->vel = r * (600/SCALE);
}
@ -1070,7 +1070,7 @@ void movePlayer(monster *m, int delta) {
playersmallspin[cpid] = cspin(0, 1, fspin) * cspin(2, 0, igospan[igo]);
if(fspin < 360) igo--; else fspin = 0;
}
nat.T = parallel_transport(nat1.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid]));
nat.T = shift_object(nat1.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid]));
rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
m->inertia[0] = playerstrafe[cpid] / delta;
m->inertia[1] = 0;
@ -1078,7 +1078,7 @@ void movePlayer(monster *m, int delta) {
}
else if(playergo[cpid]) {
playergoturn[cpid] = igospan[igo]+godir[cpid];
nat.T = parallel_transport(nat1.T, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid]));
nat.T = shift_object(nat1.T, m->ori, spin(playergoturn[cpid]) * xtangent(playergo[cpid]));
m->inertia = spin(playergoturn[cpid]) * xtangent(playergo[cpid] / delta);
}
@ -1168,7 +1168,7 @@ void movePlayer(monster *m, int delta) {
int i0 = i;
for(int a=0; a<3; a++) v[a] = (i0 % 3) - 1, i0 /= 3;
v = v * .1 / hypot_d(3, v);
shiftmatrix T1 = (i == 13) ? nat : shiftless(parallel_transport(nat.T, m->ori, v), nat.shift);
shiftmatrix T1 = (i == 13) ? nat : shiftless(shift_object(nat.T, m->ori, v), nat.shift);
cell *c3 = c2;
while(true) {
cell *c4 = findbaseAround(tC0(T1), c3, 1);
@ -1478,7 +1478,7 @@ void moveMimic(monster *m) {
// no need to care about Mirror images, as they already have their 'at' matrix reversed :|
if(WDIM == 3) {
nat.T = parallel_transport(nat.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid]));
nat.T = shift_object(nat.T, m->ori, playersmallspin[cpid] * point3(playerstrafe[cpid], 0, playergo[cpid]));
rotate_object(nat.T, m->ori, cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]));
}
else
@ -1711,10 +1711,10 @@ void moveBullet(monster *m, int delta) {
m->dead = true;
if(inertia_based) {
nat.T = parallel_transport(nat.T, m->ori, m->inertia * delta);
nat.T = shift_object(nat.T, m->ori, m->inertia * delta);
}
else
nat.T = parallel_transport(nat.T, m->ori, fronttangent(delta * SCALE * m->vel / speedfactor()));
nat.T = shift_object(nat.T, m->ori, fronttangent(delta * SCALE * m->vel / speedfactor()));
cell *c2 = m->findbase(nat, fake::split() ? 10 : 1);
if(m->parent && isPlayer(m->parent) && markOrb(itOrbLava) && c2 != m->base && !isPlayerOn(m->base))
@ -2217,14 +2217,14 @@ void moveMonster(monster *m, int delta) {
if(inertia_based) {
if(igo) return;
nat.T = parallel_transport(nat.T, m->ori, m->inertia * delta);
nat.T = shift_object(nat.T, m->ori, m->inertia * delta);
}
else if(WDIM == 3 && igo) {
ld fspin = rand() % 1000;
nat.T = parallel_transport(nat0.T, m->ori, cspin(1,2,fspin) * spin(igospan[igo]) * xtangent(step));
nat.T = shift_object(nat0.T, m->ori, cspin(1,2,fspin) * spin(igospan[igo]) * xtangent(step));
}
else {
nat.T = parallel_transport(nat0.T, m->ori, spin(igospan[igo]) * xtangent(step));
nat.T = shift_object(nat0.T, m->ori, spin(igospan[igo]) * xtangent(step));
}
if(m->type != moRagingBull && !peace::on)