Deutsch
PHP, HTML & JavaScript- Forum

3D Grafik - WebGL mit three.js

 
- Seite 1 -



HofK
Auf einen heißen Tipp von IF hin, habe ich mir mal
three.js  [...]  angeschaut. Da  [...]  (ganz unten) die ersten Resultate.
 
31.01.2016  
 



 
- Seite 46 -



HofK
Auf der Basis obigen Rechtecks mit abgerundeten Ecken eine Variante einer Box.

Discourse:  [...]  UPDATE 2022:
Github:  [...] 


const geometry = RoundedBoxFlat( width, height, depth, radiusCorner, smoothness );

function RoundedBoxFlat( w, h, d, r, s ) {

    const pi2 = Math.PI * 2;
    const n = ( s + 1 ) * 4;// number of segments
    let indices = [];
    let positions = [];
    let uvs = [];
    makeFronts( n,  1,     0 );// segments, front is 1, start index 0 is center front
    makeFronts( n, -1, n + 1 );// segments, back is -1, start index n + 1 is center back
    makeFrame( n, 2 * n + 2, 1, n + 2 );// segments, start index framing ,start index front, start index back
    const geometry = new THREE.BufferGeometry( );
    geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
    geometry.setAttribute('position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
    geometry.setAttribute('uv', new THREE.BufferAttribute( new Float32Array( uvs ), 2 ) );
    // add multimaterial groups for front, back, framing
    const vtc = n * 3 ;// vertex count
    geometry.addGroup ( 0, vtc, 0 );
    geometry.addGroup ( vtc, vtc, 1 );
    geometry.addGroup ( 2 * vtc, 2 * vtc + 3, 2  );
    geometry.computeVertexNormals( );
    return geometry;

    function makeFronts( n, side, idx ) {

        const d0 = side === 1 ? 0 : 1;
        const d1 = side === 1 ? 1 : 0;

        for ( let j = 1; j < n; j ++ ) {

            indices.push( idx, idx + d0 + j, idx + d1 + j  );

        }

        const d2 = side === 1 ? n : 1;
        const d3 = side === 1 ? 1 : n;
        indices.push( idx, idx + d2 , idx + d3 );
        positions.push( 0, 0, side * d / 2 );// center
        uvs.push( 0.5, 0.5 );

        for ( let j = 0; j < n; j ++ ) {// contour

            const qu = Math.trunc( 4 * j / n ) + 1 ;// quadrant  qu: 1..4
            const sgn = ( qu === 1 || qu === 4 ? 1: -1)// signum left/right
            const c = { x: sgn * ( w / 2 - r ), y: ( qu < 3 ? 1 : -1 ) * ( h / 2 - r ), z: side * d / 2 }// quadrant center
            const x = c.x + r * Math.cos( pi2 * ( j - qu + 1 ) / ( n - 4 ) );
            const y = c.y + r * Math.sin( pi2 * ( j - qu + 1 ) / ( n - 4 ) );
            const z = c.z;
            positions.push( x, y, z );
            const u0 = side === 1 ? 0 : 1;
            uvs.push( u0 + side * ( 0.5 + x / w ), 0.5 + y / h );

        }

    }

    function makeFrame( n, sidx, sif,  sib ) {

        let a, b, c, d, xf, yf, zf, xb, yb, zb;
        const pif = sif * 3;// position start index  front
        const pib = sib * 3;// position start index back
        let st = [];
        let idx = sidx;

        for ( let j = 0; j < n; j ++ ) {

            a = idx;
            b = idx + 1;
            c = idx + 2;
            d = idx + 3;
            indices.push( a, b, d, a, d, c );
            idx += 2;

        }

        for ( let j = 0; j < n ; j ++ ) {

            const j3 = j * 3;
            xf = positions[ pif + j3 ];
            yf = positions[ pif + j3 + 1 ];
            zf = positions[ pif + j3 + 2 ];
            xb = positions[ pib + j3 ];
            yb = positions[ pib + j3 + 1 ];
            zb = positions[ pib + j3 + 2 ];
            positions.push( xf, yf, zf, xb, yb, zb );

            if ( j === 0 ) st = [ xf, yf, zf, xb, yb, zb ];// memorize

                const v = j / n;// here only independent of section height
                uvs.push( 0, v, 1, v );

            }

            positions.push( st[ 0 ], st[ 1 ], st[ 2 ], st[ 3 ], st[ 4 ], st[ 5 ] );// end = start
            uvs.push( 0, 1, 1, 1 );

        }

    }

 
05.12.2022  
 




HofK
Noch eine weitere Variante,  [...] 



bei der man für die Textur auf der Umhüllung den Startpunkt auf einen beliebigen Quadranten legen kann. Bei den vorherigen Varianten waren die u Werte an des Start der Konstruktion gebunden und jeweils verschieden.

Dazu sind 4 zusätzliche Dreiecke zur vorherigen Variante und eine Doppelung der mittleren Punkte der Seiten erforderlich. Die Berechnung erfolgt quadrantenweise. Das gefällt mir sehr gut, da es übersichtlich ist.



Ein anderer Startpunkt.



Github [...] 
Discourse [...] 

-----------------------------------------------------------------------------------------
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/round-edged-box-flat/30012 -->
<head>
<title> RoundedBoxFlatUV </title>
<meta charset="utf-8" />
<style>
body {  margin: 0; }
</style>
</head>
<body>
</body>
<script type="module">
// @author hofk
import * as THREE from "../jsm/three.module.132.js";
import { OrbitControls } from "../jsm/OrbitControls.132.js";
const scene = new THREE.Scene( );
const camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.01, 10000 );
camera.position.set(  4, 12, 12 );
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xdedede, 1 );
const container = document.createElement('div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
const axesHelper = new THREE.AxesHelper( 10 );
scene.add( axesHelper );
const controls = new OrbitControls( camera, renderer.domElement );
const texturLoader = new THREE.TextureLoader( );
const material = [

new THREE.MeshBasicMaterial( { map: texturLoader.load('uvgrid01.png' ), wireframe: false} ),

    new THREE.MeshBasicMaterial( { map: texturLoader.load('uv_grid_opengl.jpg' ), wireframe: false} ),

        new THREE.MeshBasicMaterial( { map: texturLoader.load('uvgrid01.png' ), wireframe: false } ),

            ];
            // const material =new THREE.MeshBasicMaterial( { color: 'black',  wireframe: true } );
            const width         =  5;
            const height        =  4;
            const depth         =  9;
            const radiusCorner  =  1;
            const smoothness    =  4;
            const uStartQuadr   =  2;// tart quadrant regarding u, default is 1
            const geometry = RoundedBoxFlat( width, height, depth, radiusCorner, smoothness, uStartQuadr );// uStartQuadr optional
            geometry.computeVertexNormals( );
            const mesh = new THREE.Mesh( geometry, material );
            scene.add( mesh );
            animate( );

            function animate( ) {

                requestAnimationFrame( animate );
                renderer.render( scene, camera );

            }

            function RoundedBoxFlat( w, h, d, r, s, q ) {

                let qu = q || 1;// qu: start quadrant regarding u, optional
                const pi = Math.PI;
                let indices = [];
                let positions = [];
                let uvs = [];
                makeFronts( s,  1, 0 );// smoothness, front is 1, start index  center front
                makeFronts( s, -1, 4 * ( s + 3 ) + 1 );// smoothness, back is -1, start index center back
                makeFrame( s, 2 * ( 4 * ( s + 3 ) + 1 ), 1,  4 * ( s + 3 ) + 2 );// smoothness, start index framing ,start index front, start index back
                const geometry = new THREE.BufferGeometry( );
                geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
                geometry.setAttribute('position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
                geometry.setAttribute('uv', new THREE.BufferAttribute( new Float32Array( uvs ), 2 ) );
                // add multimaterial groups for front, back, framing
                const vtc = 4 * ( s + 2 ) * 3;
                geometry.addGroup ( 0, vtc, 0 );
                geometry.addGroup ( vtc , vtc, 1 );
                geometry.addGroup ( 2 * vtc, 2 * vtc + 3, 2 );
                geometry.computeVertexNormals( );
                return geometry;

                function makeFronts( s, side, idx ) {

                    const d0 = side === 1 ? 0 : 1;
                    const d1 = side === 1 ? 1 : 0;
                    let id = 0;

                    for ( let q = 1; q < 5; q ++ ) {// quadrants

                        id ++;

                        for ( let j = 0; j < s + 2; j ++ ) {

                            indices.push( idx, idx + d0 + id, idx + d1 + id  );
                            id ++;

                        }

                    }

                    positions.push( 0, 0, side * d / 2 );// center
                    uvs.push( 0.5, 0.5 );
                    let x, y, z, sgnX, sgnY;
                    let phi = 0;
                    const u0 = side === 1 ? 0 : 1;

                    for ( let q = 1; q < 5; q ++ ) {

                        sgnX = q === 1 || q === 4 ? 1 : -1;
                        sgnY = q < 3 ? 1 : -1 ;
                        x = Math.cos( phi ) * w / 2;
                        y = Math.sin( phi ) * h / 2;
                        z = side * d / 2;
                        positions.push( x, y, z );
                        uvs.push( u0 + side * ( 0.5 + x / w ), 0.5 + y / h  );

                        for ( let j = 0; j < s + 1; j ++ ) {

                            const c = { x: sgnX * ( w / 2 - r ), y: sgnY * ( h / 2 - r ), z: side * d / 2 }// quadrant center
                            const dPhi = pi / 2 * j / s;
                            x = c.x + r * Math.cos( phi + dPhi );
                            y = c.y + r * Math.sin( phi + dPhi );
                            z = c.z;
                            positions.push( x, y, z );
                            uvs.push( u0 + side * ( 0.5 + x / w ), 0.5 + y / h );

                        }

                        phi = phi + pi / 2;
                        x = Math.cos( phi ) * w / 2;
                        y = Math.sin( phi ) * h / 2;
                        z = side * d / 2;
                        positions.push( x, y, z );
                        uvs.push( u0 + side * ( 0.5 + x / w ), 0.5 + y / h  );

                    }

                }

                function makeFrame( s, sidx, sif, sib ) {

                    let a, b, c, d, xf, yf, zf, xb, yb, zb;
                    const pif = sif * 3;// position start index front
                    const pib = sib * 3;// position start index back
                    let idx = sidx;

                    for ( let q = 1; q < 5; q ++ ) {

                        for ( let j = 0; j < s + 2; j ++ ) {

                            a = idx;
                            b = idx + 1;
                            c = idx + 2;
                            d = idx + 3;
                            indices.push( a, b, d, a, d, c );
                            idx += 2;

                        }

                        idx += 2;

                    }

                    const ls = 2 * r * Math.sin( pi / ( s * 4 ) );// length of the outer line of a corner segment
                    const w2r = w / 2 - r;
                    const h2r = h / 2 - r;
                    const peri = 4 * w2r + 4 * h2r +  4 * s * ls;// perimeter
                    let u;
                    idx = 0;// reset

                    for ( let q = 1; q < 5; q ++ ) {

                        // console.log ( 'qu', qu );
                        u = qu / 4;

                        for ( let j = 0; j < s + 3; j ++ ) {

                            xf = positions[ pif + idx ];
                            yf = positions[ pif + idx + 1 ];
                            zf = positions[ pif + idx + 2 ];
                            xb = positions[ pib + idx ];
                            yb = positions[ pib + idx + 1 ];
                            zb = positions[ pib + idx + 2 ];
                            positions.push( xf, yf, zf, xb, yb, zb );
                            idx += 3;
                            // console.log ( 'u ', u );
                            uvs.push( u , 0, u, 1 );

                            if ( j === 0 )     { u -= q === 1 || q === 3 ? h2r / peri : w2r / peri; }

                            if ( j === s + 1 ) { u -= q === 1 || q === 3 ? w2r / peri : h2r / peri; }

                            if ( j > 0 && j < s + 1 ) { u -= ls / peri; }

                        }

                        qu = 4 - ( ( 5 - qu ) % 4 );// cyclic next quadrant with respect to u

                    }

                }

            }

            </script>
            </html>
 
09.12.2022  
 




HofK
Eine weitere Figur,die ich im Netz verwenden werde. Sie ist aus losen Punkten zusammengesetzt.

 [...] 

Github  [...] 
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/create-circle-with-fuzzy-edge-made-of-individual-random-particles/30150/9 -->
<head>
<title> SphereWithRandomPointsl </title>
<meta charset="utf-8" />
<style>

body{

    overflow: hidden;
    margin: 0;

}

</style>
</head>
<body> </body>
<script type="module">
// @author hofk
import * as THREE from'../jsm/three.module.135.js';
import { OrbitControls} from'../jsm/OrbitControls.135.js'
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera( 60, innerWidth / innerHeight, 0.001, 100);
camera.position.set( 1, 1, 2 );
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
renderer.setClearColor( 0xdedede, 1 );
document.body.appendChild(renderer.domElement);

window.addEventListener("resize", (event) => {

    camera.aspect = innerWidth / innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(innerWidth, innerHeight);

});

let controls = new OrbitControls(camera, renderer.domElement);
let helper = new THREE.AxesHelper( );
scene.add( helper );
const n = 25000;// points count
const dri = 0.07;// radius inner difference
const r = 0.6;// radius main
const dro = 0.4;// radius outer difference
const geometry = PointsSphere( n, dri, r, dro );
const pointsMaterial = new THREE.PointsMaterial( { size: 0.01, color: 0xff00ff } );
const spherePoints = new THREE.Points( geometry, pointsMaterial );
scene.add( spherePoints );
renderer.setAnimationLoop( ( ) => { renderer.render(scene, camera); } );
// .....................................

function PointsSphere( n, dri, r, dro ) {

    // n: points count,  dri: inner difference , r: radius main, dro: outer difference
    const pts = [];

    for( let i = 0; i < n ; i++){

        const inout = ( Math.random( ) - 0.5 ) * 2;
        const lim = ( inout >= 0 ? dro : dri );
        const rand = r + Math.pow( Math.random( ), 3 ) * lim * inout;
        const θ = Math.PI * 2 * Math.random( );
        const φ = Math.acos( 2 *  Math.random( ) - 1 );
        const ps = new THREE.Vector3( Math.cos( θ ) * Math.sin( φ ),  Math.sin( θ ) * Math.sin( φ ),  Math.cos( φ ) );
        pts.push( ps.multiplyScalar( rand ) );

    }

    const geometry = new THREE.BufferGeometry( ).setFromPoints( pts );
    return geometry;

}

</script>
</html>
 
21.12.2022  
 




HofK


Ein Jahr ist wieder vorüber und die gesammelten Beispiele von Discourse stehen seit einigen Tagen zum Download bereit.  [...] 
 
15.01.2023  
 




HofK
Bei der Arbeit am Netz hatte ich ein Problem mit der Transparenz. Je nach Kameraposition verschwanden die transparenten Flügel der Biene in der transparenten Blase.

Transparenz gemischt ist ein oftmals schwieriges Problem. In meinem Fall gab es eine einfache Lösung - einfach, wenn man es dann kennt.

Discourse:  [...] 

Seite in der Sammlung mit Lösung:  [...] 

 
10.02.2023  
 




HofK
Eine neue spezielle Geometrie:

Dynamisches Mondphasen Panel



Siehe unter Github  [...] 
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/addon-to-create-special-extended-geometries/1855/12 -->
<head>
<title> MoonPhases </title>
<meta charset="utf-8" />
<style>

body{

    overflow: hidden;
    margin: 0;

}

</style>
</head>
<body></body>
<script type="module">
// @author hofk
import * as THREE from "../jsm/three.module.149.js";
import { OrbitControls } from "../jsm/OrbitControls.149.js";
const scene = new THREE.Scene( );
const camera = new THREE.PerspectiveCamera( 55, innerWidth / innerHeight, 0.01, 1000 );
camera.position.set(  0, 1, 4 );
const renderer = new THREE.WebGLRenderer( );
renderer.setSize( innerWidth, innerHeight );
renderer.setClearColor( 0xdedede );
document.body.appendChild(renderer.domElement);
const pointLight1 = new THREE.PointLight( 0xffff00, 1.1 );
pointLight1.position.set( 1, 2, 7 );
scene.add( pointLight1 );
const pointLight2 = new THREE.PointLight( 0xffff00, 1.1 );
pointLight2.position.set( -1, -2, -7 );
scene.add( pointLight2 );
new  OrbitControls( camera, renderer.domElement );
const material = new THREE.MeshPhongMaterial( { color: 0xfbfb23, wireframe: true,  side: THREE.DoubleSide } );
const moonGeo = MoonPhases( 1, 0.2, 32, 0 );
const moon = new THREE.Mesh( moonGeo, material );
scene.add( moon );
let t = 0;
animate( );

function animate( ) {

    t += 0.01;
    requestAnimationFrame( animate );
    moonGeo.calculatePositions( t );// phase dynamic
    renderer.render( scene, camera );

}

function MoonPhases( radius, depth, heightSegments, phase ) {

    const g = new THREE.BufferGeometry( );
    const pi = Math.PI;
    const pi2 = pi * 2;
    const hs2 = heightSegments * 2;// equals triangles per side
    const phs = phase || 0.1;
    let indices = [];
    let φ;
    let ib;// index back

    for ( let i = 0; i < hs2; i += 2 ) {

        indices.push( i, i + 2, i + 1,  i + 1, i + 2, i + 3 );// front

    }

    for ( let i = 0; i < hs2; i += 2 ) {

        ib = i + hs2 + 2;
        indices.push( ib, ib + 1, ib + 2,  ib + 1, ib + 3, ib + 2 );// back

    }

    for ( let i = 0; i < hs2; i += 2 ) {

        ib = i + hs2 + 2;
        indices.push( i, ib, ib + 2,          i,  ib + 2, i + 2 );// framing right
        indices.push( ib + 1, i + 1, i + 3,   ib + 1, i + 3, ib + 3 );// framing left

    }

    const sidePosCount = ( heightSegments + 1 ) * 2 ;
    g.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
    g.setAttribute('position', new THREE.BufferAttribute( new Float32Array( sidePosCount * 2 * 3 ), 3 ) );

    g.calculatePositions = function( t ) {

        t = t % pi2;
        const leftEdge  = t => t < pi ? Math.cos( t ) : -1;
        const rightEdge = t => t < pi ? 1 : -Math.cos( t );
        φ = 0;

        for ( let i = 0; i < sidePosCount; i += 2 ) {

            // front
            g.attributes.position.setXYZ(  i    , radius * rightEdge( t ) * Math.sin( φ ), -radius * Math.cos( φ ), depth / 2 );
            g.attributes.position.setXYZ(  i + 1, radius * leftEdge( t )  * Math.sin( φ ), -radius * Math.cos( φ ), depth / 2 );
            //  back
            ib = i + hs2 + 2;
            g.attributes.position.setXYZ( ib    , radius * rightEdge( t ) * Math.sin( φ ), -radius * Math.cos( φ ), -depth / 2 );
            g.attributes.position.setXYZ( ib + 1, radius * leftEdge( t )  * Math.sin( φ ), -radius * Math.cos( φ ), -depth / 2 );
            φ += pi / heightSegments;

        }

        g.attributes.position.needsUpdate = true;
        g.computeVertexNormals( );

    }

    g.calculatePositions( phs * pi2 );
    return g;

}

</script>
</html>
 
15.02.2023  
 




p.specht

(Off Topic Mit welchem Programm werden eigentich diese Hochglanz-Werbefilme erzeugt, wo glänzende Materialien wie Apfelsaft oder Schokolade dynamisch in Behälter strömen?
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'...
15.02.2023  
 




HofK
p.specht (15.02.2023)
(Off Topic Mit welchem Programm ...


Da gibt es eine Reihe sehr professioneller Software. Die Preise sind nichts für privat.

Und Firmen wie z.B. Mynd ( mal googeln) nutzen sicher verschiedene solcher Systeme.
 
24.02.2023  
 




HofK
Vor einem Jahr habe ich an einer prozedural erzeugten Figur gearbeitet. Siehe weiter oben. Allerdings habe ich das nur als Studie gemacht und nicht komplett ausgearbeitet.

Ich bin jetzt auf eine recht professionelle und frei verfügbare Variante gestoßen. Sie arbeitet ohne Skelett, benutzt aber auch Kugelgelenke.

Siehe Github:  [...] 

Ich habe sie erfolgreich in mein derzeitiges Projekt integriert.

Die README ist vom Autor sehr umfangreich bebildert und mit Live-Beispielen versehen.

Dieser dynamische Kerl ist sehenswert.

 
24.02.2023  
 




HofK
Ein weiteres paralleles Projekt erfordert Zeit und lässt wenig übrig.



Ein Fehler zeigte, dass bei komplexen Rechnungen die Präzision zum Problem werden kann. Siehe  [...] 



Es gab eine glänzende Analyse von PavelBoytchev, der in letzter Zeit sehr viele professionelle Lösungen auf Fragen im Forum postet. Immer mit sehr gut dokumentierten Codepens. Da ich mit der Sammlung aus Zeitgründen nicht hinterher komme, habe ich in der Sammlung Links zu  [...]  und auch zu  [...]  hinzugefügt.

 
01.04.2023  
 




HofK
Mittlerweile habe ich eine stabile Grundkonstruktion für das Projekt.



Allerdings war es nicht so einfach wie gedacht.

Eine Frage bei discourse brachte mich etwas weiter [...] 

Dabei eine schwer verdauliche Quelle, die Pavel Boytchev für mich sinnvoll fand.
Ich habe sie umgangen, siehe discourse !
 
20.06.2023  
 




HofK
Wie schnell die Zeit vergeht.

Seit dem letzten Beitrag ist nun bereits ein halbes Jahr vergangen.

Das parallele Projekt ist eine kommerzielle Sache und daher muß das vorherige open source Projekt pausieren.

Das Projekt wird umfangreicher als zunächst angedacht, denn um die Geometrien sinnvoll erzeugen zu können brauchte es noch einen speziellen web-Editor. Die Sache ist noch in Arbeit.

Nebenbei bin ich gerade mal dazu gekommen zum Jahresende die Sammlung der Beispiele von discourse zu vervollständigen. Da gibt es viele interessante Beispiele.

Insbesondere Pavel Boytchev ( Researcher and educator Faculty of Mathematics and Informatics, Sofia University  )
hat sehr viele lehrreiche Beiträge mit Beispielen im Forum verfasst.

Siehe  [...] 

Auch auf seiner Seite  [...]  finden sich interessante Beispiele. Auch reines WebGL ohne three.js.
 
30.12.2023  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

332.597 Betrachtungen

Unbenanntvor 0 min.
HofK vor 23 Tagen
Rschnett24.08.2024
Michael W.28.03.2024
Thomas Zielinski17.02.2024
Mehr...

Themeninformationen



Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie