HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /home/panomity.de/vr.panomity.com/plugins/walk/walk.js
/**
 * Walk-Through-Modus für CMS4VR.
 *
 * Nutzt krpanos Tiefenkarten-Navigation (depthmap_navigation): mit aktivierter
 * Szenen-Tiefenkarte kann man mit WASD/Pfeilen durch den Raum GEHEN (echte
 * Parallaxe, Wand-Kollision) und über die Szenen-Hotspots weiter durch die
 * Wohnung. Die Tastensteuerung wird nur im Walk-Modus scharfgeschaltet, damit
 * WASD sonst (z.B. im Chat) nicht ins Leere greift.
 */

const walkMode = { on: false, watcher: null };

function walkKrpano() {
    return (typeof krpano !== 'undefined') ? krpano : document.getElementById('krpanoSWFObject');
}
function walkLang() {
    return (typeof ollamaChatConfig !== 'undefined' && ollamaChatConfig.language) || 'en';
}
function walkText(de, en) { return walkLang() === 'de' ? de : en; }

// Tasten-Handler der Navigation an/aus (verhindert WASD-Störungen außerhalb Walk).
function walkSetKeys(active) {
    const k = walkKrpano();
    try {
        const ev = k.get('events[depthmap_navigation]');
        if (ev) {
            ev.onkeydown = active ? 'depthmap_handlekey(1);' : '';
            ev.onkeyup   = active ? 'depthmap_handlekey(0);' : '';
        }
        if (!active) {
            ['forward', 'backward', 'left', 'right', 'up', 'down', 'faster', 'jump']
                .forEach(p => { try { k.set('walkaround.' + p, 0); } catch (e) { /* egal */ } });
        }
    } catch (e) { /* Plugin evtl. noch nicht geladen */ }
}

function walkEnableDepth(on) {
    const k = walkKrpano();
    try {
        const dm = k.get('image.depthmap');
        if (dm) dm.enabled = on;
    } catch (e) { /* Szene ohne Tiefenkarte */ }
}

function walkToggle() {
    const k = walkKrpano();
    walkMode.on = !walkMode.on;
    const btn = document.getElementById('walk-button');

    if (walkMode.on) {
        walkEnableDepth(true);
        walkSetKeys(true);
        // Beim Szenenwechsel die Tiefenkarte der neuen Szene aktiv halten.
        walkMode.watcher = setInterval(() => walkEnableDepth(true), 1200);
        if (btn) btn.classList.add('active');
        walkHint(true);
        walkShowPad(true);
        // krpano fokussieren, damit WASD/Pfeile sofort ankommen.
        try { const el = document.getElementById('pano') || (k.get && k.get('canvas')); if (el && el.focus) el.focus(); } catch (e) { /* egal */ }
    } else {
        clearInterval(walkMode.watcher);
        walkSetKeys(false);
        walkStopAll();
        walkEnableDepth(false);
        // Zur Aufnahmeposition zurück.
        try { k.call('tween(view.tx, 0.0, 0.4); tween(view.ty, 0.0, 0.4); tween(view.tz, 0.0, 0.4);'); } catch (e) { /* egal */ }
        if (btn) btn.classList.remove('active');
        walkHint(false);
        walkShowPad(false);
    }
}
window.walkToggle = walkToggle;

// Bewegungsrichtung setzen (fuer On-Screen-Steuerung + Touch).
function walkSet(dir, on) {
    const k = walkKrpano();
    try { k.set('walkaround.' + dir, on ? 1 : 0); } catch (e) { /* egal */ }
}
function walkStopAll() {
    ['forward', 'backward', 'left', 'right'].forEach(d => walkSet(d, 0));
}

// Sichtbare Geh-Steuerung (Steuerkreuz) — macht Bewegung offensichtlich,
// funktioniert auch auf Touch-Geraeten ohne Tastatur.
function walkShowPad(show) {
    let pad = document.getElementById('walk-pad');
    if (show) {
        if (pad) { pad.style.display = 'grid'; return; }
        pad = document.createElement('div');
        pad.id = 'walk-pad';
        const defs = [
            ['forward', '▲', 'gf'], ['left', '◀', 'gl'], ['right', '▶', 'gr'], ['backward', '▼', 'gb'],
        ];
        defs.forEach(([dir, glyph, cls]) => {
            const btnEl = document.createElement('button');
            btnEl.className = 'walk-pad-btn ' + cls;
            btnEl.textContent = glyph;
            const start = (e) => { e.preventDefault(); walkSet(dir, true); };
            const stop = (e) => { e.preventDefault(); walkSet(dir, false); };
            btnEl.addEventListener('pointerdown', start);
            btnEl.addEventListener('pointerup', stop);
            btnEl.addEventListener('pointerleave', stop);
            btnEl.addEventListener('pointercancel', stop);
            pad.appendChild(btnEl);
        });
        document.body.appendChild(pad);
    } else if (pad) {
        pad.style.display = 'none';
    }
}

function walkHint(show) {
    let h = document.getElementById('walk-hint');
    if (show) {
        if (!h) {
            h = document.createElement('div');
            h.id = 'walk-hint';
            document.body.appendChild(h);
        }
        h.textContent = walkText(
            'Begehen-Modus — mit den Pfeilen (oder WASD) gehen · ziehen zum Umsehen · Szenen anklicken für den nächsten Raum',
            'Walk mode — walk with the arrows (or WASD) · drag to look · click scenes for the next room');
        h.style.display = 'block';
    } else if (h) {
        h.style.display = 'none';
    }
}

function walkInit() {
    const tryInit = (attempt) => {
        const k = walkKrpano();
        if (!k || !k.get) {
            if (attempt < 40) setTimeout(() => tryInit(attempt + 1), 500);
            return;
        }
        if (document.getElementById('walk-button')) return;
        // Sicherheitshalber Tasten der Navigation deaktivieren (nur Walk-Modus schaltet sie scharf).
        walkSetKeys(false);

        const btn = document.createElement('div');
        btn.id = 'walk-button';
        btn.title = walkText('Begehen — durch die Wohnung gehen', 'Walk — move through the apartment');
        btn.innerHTML = '<i class="mdi mdi-walk"></i><span>' + walkText('Gehen', 'Walk') + '</span>';
        btn.addEventListener('click', walkToggle);
        document.body.appendChild(btn);
        console.log('Walk: ready');
    };
    tryInit(0);
}
window.walkInit = walkInit;
walkInit();