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 35 -



p.specht
Meister!
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen...
12.06.2020  
 




HofK
Ich habe die Sache mal auf meine ältere Variante
ProfiledContourGeometry MultiMaterial  [...]   [...]  übertragen.

Dabei sind diverse Änderungen in der Struktur der Geometrie nötig.



Dort probieren [...] 

(Update: Es gab einen Tippfehler im Link. Ordner ...GeometrUVs ohne y)
<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/profiledcontourgeometry-multimaterial/5801 -->
<head>
<title> ProfiledContourGeometryUVs  </title>
<meta charset="utf-8" />
<style>

body {

    margin: 0;

}

</style>
</head>
<body> </body>
<script src="../js/three.min.117.js"></script>
<script src="../js/OrbitControls.117.js"></script>
<script>
'use strict'
// @author hofk
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( -6, 18, 20 );
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const controls = new THREE.OrbitControls( camera, renderer.domElement );
const light = new THREE.DirectionalLight( 0xffffff, 0.6);
light.position.setScalar( 10 );
scene.add( light );
scene.add(new THREE.AmbientLight( 0xffffff, 0.8));
const helper = new THREE.GridHelper( 20, 20);
scene.add( helper );
const detail = 5;
let profileShape1 = [];

for ( let i = detail; i > -1; i --){

    profileShape1.push ( 1.8 * Math.cos( i / detail * Math.PI * 2 ), 1.8 * Math.sin( i / detail * Math.PI * 2 ) );

}

const contour1 = [
-3,  4,
0,  4,// here only to show that angle of 180° horizontal works
4,  4,
2,  1,
4, -2,
0, -3,
-4, -3,
-4,  0
];
const profileShape2 = [ -1,1, 1,1, 1,-1, -1,-1 ];
const contour2 = [
2,-2,
2, 0,
4, 4,
9, 4,
9, 2,// here only to show that angle of 180° vertikal works
9, 0,
];
const  tex1 = new THREE.TextureLoader().load('uvgrid01.png' );
const  tex2 = new THREE.TextureLoader().load('beech.jpg' ); // License: free, Non-commercial use
const  tex3 = new THREE.TextureLoader().load('pngwing-com-water.png' );// License:  free, Non-commercial use
//const m0 = new THREE.MeshPhongMaterial( { color: 0xfa0001, side: THREE.DoubleSide } );
//const m1 = new THREE.MeshPhongMaterial( { color: 0xff7b00, side: THREE.DoubleSide } );
//const m2 = new THREE.MeshPhongMaterial( { color: 0xf9f901, side: THREE.DoubleSide } );
const m0 = new THREE.MeshPhongMaterial( { map: tex3, side: THREE.DoubleSide } );
const m1 = new THREE.MeshPhongMaterial( { map: tex2, side: THREE.DoubleSide } );
const m2 = new THREE.MeshPhongMaterial( { map: tex1, side: THREE.DoubleSide } );
const m3 = new THREE.MeshPhongMaterial( { color: 0x008601, side: THREE.DoubleSide } );
const m4 = new THREE.MeshPhongMaterial( { color: 0x01bbbb, side: THREE.DoubleSide } );
const m5 = new THREE.MeshPhongMaterial( { color: 0x250290, side: THREE.DoubleSide } );
//const m3 = new THREE.MeshPhongMaterial( { map: tex1, side: THREE.DoubleSide } );
//const m4 = new THREE.MeshPhongMaterial( { map: tex1, side: THREE.DoubleSide } );
//const m5 = new THREE.MeshPhongMaterial( { map: tex1, side: THREE.DoubleSide } );
const m6 = new THREE.MeshPhongMaterial( { color: 0xfc4ea5, side: THREE.DoubleSide } );
const m7 = new THREE.MeshPhongMaterial( { color: 0x83058a, side: THREE.DoubleSide } );
const m8 = new THREE.MeshPhongMaterial( { color: 0x83058a, side: THREE.DoubleSide } );
const materials = [ m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8 ];
//............................................................ matPerSquare, contourClosed
const frame1 = ProfiledContourUV( profileShape1, contour1, materials, false , true );
scene.add( frame1 );
frame1.position.x = -5;
frame1.position.z = 3;
frame1.rotation.y = 2.8;
const frame2 = ProfiledContourUV( profileShape2, contour2, materials, true, false );
frame2.position.z = -4;
scene.add( frame2 );
render();

function render() {

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

}

function ProfiledContourUV( profileShape, contour, materials, matPerSquare, contourClosed ) {

    // creates group of frame strips, non indexed BufferGeometry
    const len = ( x, y, z ) => Math.sqrt( x * x + y * y + z * z );
    const dot = (x1, y1, z1, x2, y2, z2) => ( x1 * x2 + y1 * y2 + z1 * z2 );
    matPerSquare = matPerSquare!== undefined ? matPerSquare : false;
    contourClosed = contourClosed !== undefined ? contourClosed : true;
    if( contourClosed ) contour.push( contour[ 0 ], contour[ 1 ] );
    const hs1 = contour.length / 2;
    const rs1 = profileShape.length / 2;
    const hs = hs1 - 1;// height segments
    const rs = rs1 - 1;// radius segments
    let	vtx = [];// rs1 many vertex colums
    let	frmpos = [];// hs many geometries and meshes
    let	frmuvs = [];// hs many uv's'

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

        vtx.push( [] );
        frmpos.push( [] );
        frmuvs.push( [] );

    }

    vtx.push( [] );// last colum
    let gFrame = [];// geometries of frame strips
    let frame = [];// meshes of frame strips
    const fGroup = new THREE.Group( );
    let i1, i2, i3, i6, j1, j3;
    let xc0, yc0, xc1, yc1, xc2, yc2, xSh, xDiv;
    let dx, dy, dx0, dy0, dx2, dy2;
    let e0x, e0y,e0Length, e2x, e2y, e2Length, ex, ey, eLength;
    let xd, phi, bend;
    let x, y, z, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
    let a, u1, u2, u3, u4, d2, d3;
    const epsilon = 0.000001;

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

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

            i2 = 2 * i;
            xc1 = contour[ i2 ];
            yc1 = contour[ i2 + 1 ];

            if ( i === 0 ) {

                xc0 = contour[ ( hs - 1 ) * 2 ];// penultimate point
                yc0 = contour[ ( hs - 1 ) * 2 + 1 ];

            } else {

                xc0 = contour[ i2 - 2 ];// previous point
                yc0 = contour[ i2 - 1 ];

            }

            if ( i === hs ) {

                xc2 = contour[ 2 ];// second point
                yc2 = contour[ 3 ];

            } else {

                xc2 = contour[ i2 + 2 ];// next point
                yc2 = contour[ i2 + 3 ];

            }

            if ( !contourClosed ) {

                if ( i === 0 ) {

                    // direction
                    dx2 = xc2 - xc1;
                    dy2 = yc2 - yc1;
                    // unit vector
                    e2Length = Math.sqrt( dx2 * dx2 + dy2 * dy2 );
                    e2x = dx2 / e2Length;
                    e2y = dy2 / e2Length;
                    // orthogonal
                    ex = e2y;
                    ey = -e2x;

                }

                if ( i === hs ) {

                    // direction
                    dx0 = xc1 - xc0;
                    dy0 = yc1 - yc0;
                    // unit vector
                    e0Length = Math.sqrt( dx0 * dx0 + dy0 * dy0 );
                    e0x = dx0 / e0Length;
                    e0y = dy0 / e0Length;
                    // orthogonal
                    ex = e0y;
                    ey = -e0x;

                }

                xDiv = 1;
                bend = 1;

            }

            if ( ( i > 0 && i < hs ) || contourClosed ) {

                // directions
                dx0 = xc0 - xc1;
                dy0 = yc0 - yc1;
                dx2 = xc2 - xc1;
                dy2 = yc2 - yc1;

                if( Math.abs( ( dy2 / dx2 ) - ( dy0 / dx0 ) ) < epsilon ) {// prevent 0

                    dy0 += epsilon;

                }

                if( Math.abs( ( dx2 / dy2 ) - ( dx0 / dy0 ) ) < epsilon ) {// prevent 0

                    dx0 += epsilon;

                }

                // unit vectors
                e0Length = Math.sqrt( dx0 * dx0 + dy0 * dy0 );
                e0x = dx0 / e0Length;
                e0y = dy0 / e0Length;
                e2Length = Math.sqrt( dx2 * dx2 + dy2 * dy2 );
                e2x = dx2 / e2Length;
                e2y = dy2 / e2Length;
                // direction transformed
                ex = e0x + e2x;
                ey = e0y + e2y;
                eLength = Math.sqrt( ex * ex + ey * ey );
                ex = ex / eLength;
                ey = ey / eLength;
                phi = Math.acos( e2x * e0x + e2y * e0y ) / 2;
                bend = Math.sign( dx0 * dy2 - dy0 * dx2 );// z cross -> curve bending
                xDiv = Math.sin( phi );

            }

            xSh = profileShape[ j * 2 ];
            xd = xSh / xDiv;
            dx = xd * bend * ex;
            dy = xd * bend * ey;
            x = xc1 + dx;
            y = yc1 + dy;
            z = profileShape[ j * 2 + 1 ];// ySh
            vtx[ j ].push( x, y, z );// store vertex
            //dApex = xd * Math.cos( phi );

        }

    }

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

        j1 = j + 1;
        j3 = 3 * j;

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

            i3 = 3 * i;
            i6 = i3 + 3;
            x1 = vtx[ j ][ i3 ];
            y1 = vtx[ j ][ i3 + 1 ];
            z1 = vtx[ j ][ i3 + 2 ] ;
            x2 = vtx[ j1 ][ i3 ];
            y2 = vtx[ j1 ][ i3 + 1 ];
            z2 = vtx[ j1 ][ i3 + 2 ];
            x3 = vtx[ j1 ][ i6 ];
            y3 = vtx[ j1 ][ i6 + 1 ];
            z3 = vtx[ j1 ][ i6 + 2 ];
            x4 = vtx[ j ][ i6 ];
            y4 = vtx[ j ][ i6 + 1 ];
            z4 = vtx[ j ][ i6 + 2 ];
            frmpos[ j ].push( x1, y1, z1, x2, y2, z2, x4, y4, z4, x2, y2, z2, x3, y3, z3, x4, y4, z4 );
            a = len( x4 - x1, y4 - y1, z4 - z1 );
            d2 = dot( x4 - x1, y4 - y1, z4 - z1, x2 - x1, y2 - y1, z2 - z1 ) / a;
            d3 = dot( x1 - x4, y1 - y4, z1 - z4, x3 - x4, y3 - y4, z3 - z4, ) / a;

            if ( d2 >= 0 && d3 >= 0 ) {

                u1 = 0;
                u2 = d2 / a;
                u3 = 1 - d3 / a;
                u4 = 1;

            }

            if ( d2 >= 0 && d3 < 0 ) {

                u1 = 0;
                u2 = d2 / ( a - d3 );
                u3 = 1;
                u4 = 1 + d3 / ( a - d3 );

            }

            if ( d2 < 0 && d3 < 0 ) {

                u1 = -d2 / ( a - d2 - d3 );
                u2 = 0;
                u3 = 1;
                u4 = 1 + d3 / ( a - d2 - d3  );

            }

            if ( d2 < 0 && d3 >= 0 ) {

                u1 = -d2 / ( a - d2  );
                u2 = 0;
                u3 = 1 - d3 / ( a - d2  );
                u4 = 1;

            }

            frmuvs[ j ].push( u1, 1, u2, 0, u4, 1, u2, 0, u3, 0, u4, 1 );

        }

    }

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

        gFrame[ j ] = new THREE.BufferGeometry( );
        gFrame[ j ].setAttribute('position', new THREE.BufferAttribute( new Float32Array( frmpos[ j ] ), 3 ) );
        gFrame[ j ].setAttribute('uv', new THREE.BufferAttribute( new Float32Array( frmuvs[ j ] ), 2 ) );

        if ( matPerSquare ) {// MultiMaterial support (for each square)

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

                gFrame[ j ].addGroup( i * 6, 6, j * hs + i );

            }

            frame[ j ] = new THREE.Mesh( gFrame[ j ], materials );

        } else {// material per frame strip

            frame[ j ] = new THREE.Mesh( gFrame[ j ], materials[ j ] );

        }

        gFrame[ j ].computeVertexNormals( );
        fGroup.add( frame[ j ] )

    }

    return fGroup;// group of frame strips

}

</script>
</html>
 
15.06.2020  
 




HofK
Nun ist auch eine Version im Addon THREEg verfügbar. [...] 

Abweichend von den sonstigen Beispielen wird hier nicht nur die Geometrie erzeugt, sondern daraus in zwei Varianten für die Anordnung der Materialien eine Gruppe von Meshes erzeugt. Diese wird mit scene.add( ); der Anwendung hinzugefügt.
const frame = new THREE.Group( );
frame.createProfiledContourUV = THREEg.createProfiledContourUV;
// ......................................................... matPerSquare, contourClosed
frame.createProfiledContourUV( profileShape, contour, materials, false , true );
scene.add( frame );

In der obigen Variante mit der eigenständigen Funktion wird die Definition der Gruppe innerhalb der Funktion erledigt.
 
16.06.2020  
 




p.specht
Schaffen ältere Computer das? Langsam wird die Sache vielleicht zu abhängig vom Einsatz teurer Grafikkarten...
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen...
17.06.2020  
 




HofK
p.specht (17.06.2020)
... ältere Computer ... zu abhängig vom Einsatz teurer Grafikkarten...


Das ist immer relativ. Die Sachen, die ich hier mache, laufen wenn es um bewegte Grafik geht zwar nicht mehr auf meinem alten Android 4.4 Tablet von 2014, aber sehr wohl auf meinem Mittelklasse Smartphone von 2017. Bei "richtigen" Computern ist die Sache entspannter. Mein leicht defektes Notebook etwas gehobener Ausstattung (siehe weiter oben) aus dem Produktionsjahr 2012 hat keine Probleme. Wenn man allerdings aufwändige Grafikspiele im Sinn hat, sollte es etwas neueres und teures sein - Gaming PC mit "ordentlich teurer" Grafikkarte!

Tablets mit Android 4.4 sind bei vielen Dingen bereits außen vor. Selbst die Öffentlich Rechtlichen für die wir alle zwangsweise "blechen" meinen, soetwas nicht mehr unterstützen zu müssen. Dabei haben sich die meisten Filme selbst nicht geändert (ich meine kein 4K u.ä.) und sind von der Technik problemlos beherrschbar. Aber es macht Aufwand, für verschiedene Android Versionen zu programmieren. Habe das selbst vor 6 Jahren getestet.
 
18.06.2020  
 




Jörg
Sellmeyer
Ließen sich diese Algorithmen eigentlich auch irgendwie nach Profan übertragen?
Ich staune immer wieder, wenn ich diesen Thread aufpoppen sehe und denke: Wow - wenn ich nur wüßte, wie und wo ich das mal einsetzen könnte.
In Profan jedenfalls eher mal als in PHP/Javaskript.
 
XProfan X4
Windows XP SP2 XProfan X4
... und hier mal was ganz anderes als Profan ...
19.06.2020  
 



 
- Seite 36 -



HofK
Jörg Sellmeyer (19.06.2020)
Ließen sich diese Algorithmen eigentlich auch irgendwie nach Profan übertragen?


Vor knapp 10 Jahren habe ich mit XProfan 11 einige Tests auf der Basis von OpenGL gemacht. In der Hilfe zu XProfan 11 gibt es dazu Kapitel.
Ich wollte sehen, was das ist. Weit vor der Zeit als ich auf three.js gestoßen bin.

Dieses Framework baut auf WebGL auf. Zwischen OpenGL und WebGL gibt es natürlich einige Unterschiede.

Betrachtet man meine Programme die hauptsächlich 3D Geometrie bearbeiten, so sind die eigentlichen Algorithmen unabhängig von einer speziellen Programmiersprache und einem bestimmten Framework. Anders sieht es mit dem ganzen Drumherum wie Licht, Bewegung usw. aus.

Immer wenn = new THREE. auftaucht, benutze ich fertig konfigurierte Dinge aus three.js. Beispielsweise auch mal = new THREE.Vector3()

Da ich aber z.B. in der Vektorrechnung lieber komponentenweise selbst programmiere, ist das in meinen Programmen selten. Das hat Vor- und Nachteile. Mit new... hat man mehr Objekte und verbraucht Ressourcen, der Code wird eventuell kürzer. Jeder hat seine Vorlieben.

Vorteil:
Die komponentenweise Rechnung ist problemlos auf beliebige Sprachen übertragbar. Nur Änderungen in der konkreten Syntax.


Ein gutes Beispiel ist die Triangulation impliziter Flächen. Siehe weiter oben. Das Original war in Pascal programmiert, die Anzeige erfolgte mit povray.

Allerdings habe ich da zusätzlich die Struktur des Algorithmus und damit des Programms komplett überarbeitet.

Einfach mal mit dem verfügbaren XProfan an einem zunächst einfachen Beispiel testen, wie das geht.

Gerade wiedergefunden:



Rotiert natürlich schön.
 
26.06.2020  
 




HofK
In den letzten Wochen blieb wegen anderer, wichtigerer Dinge kaum Zeit für three.js. Habe es gerade so geschafft, das Forum discourse.threejs.org  [...]  zu verfolgen und die Beispiele zu sammeln, zu bearbeiten und hochzuladen.

Da gibt es eine ganze Reihe neuer und interessanter Dinge. Einfach mal in die Sammlung bei 2020 schauen.  [...] 

 [...] 
 
26.08.2020  
 




HofK
In den Beispielen von discourse.threejs.org wird seit 2020 von der Variante mit ES6 Modulen Gebrauch gemacht. Diese Beispiele lassen sich wegen der Sicherheitsrichtlinien nicht lokal im Browser aufrufen. Deshalb habe ich den Punkt
"Local use of the examples" neu verfasst.



Für Windows 10 (nur das kann ich testen) habe ich eine sehr anfängerfreundliche Variante gefunden. Der lokale Server Apache kommt ohne Installation aus.

Die Anleitung in Englisch siehe unter  [...] 

Sollte jemand eine entsprechend einfache Variante (mit Apache?) für andere Betriebssysteme testen und kurz beschreiben, kann ich das hinzufügen.
 
________________________________________________________________

Lokale Nutzung der Beispiele

Die Modulversion three.js erfordert unbedingt einen lokalen Server.
Ab 2020 sind bereits viele Beispiele in dieser Form erstellt worden.
Ende des Jahres werden sie als zip-Datei zum Download zur Verfügung stehen.

Eine besonders einfache Variante bietet der lokale Server Apache.
Er ist auch im XAMPP-Paket enthalten.

Solo benötigt er keine Installation (nur unter Windows 10 getestet).

Rufen Sie die Seite  [...]  auf.

Laden Sie z.B. httpd-2.4.46-win64-VS16.zip herunter (verwenden Sie die aktuelle Version 64/32 bit)

Entpacken Sie die Datei und kopieren Sie den Ordner Apache24 nach C:\

Abhängig von der bereits auf dem Computer installierten Software können Dateien fehlen und es kann eine Meldung erscheinen. Da Apache in C++ geschrieben ist, benötigt das Programm eine entsprechende Laufzeitumgebung unter Windows. Diese wird von der Compiler-Software Visual C++ zur Verfügung gestellt und ist oft bereits von anderer Software installiert. Es handelt sich um die Datei VCRUNTIME140.dll, sie muss vorhanden sein.

Um den lokalen Server zu starten, führen Sie die Datei C:\Apache24\bin\httpd.exe aus.
Das sich öffnende Fenster kann minimiert werden.

Wenn Sie den Standardordner \Apache24\htdocs für die Beispiele ändern möchten, müssen Sie die Datei httpd.conf im Ordner \Apache24\conf editieren.

Die Zeilen

DocumentRoot "${SRVROOT}/htdocs"
<Directory "${SRVROOT}/htdocs">

ändern Sie auf z.B.

DocumentRoot "D:\collection"
<Directory "D:\collection">

Danach Apache neu starten!

Geben Sie 127.0.0.1 oder localhost in den Browser ein und es wird der Index des Ordners oder die Webseite angezeigt, falls eine index.html vorhanden ist. Da die Beispiele der Sammlung in den Ordnern nicht als index.html, sondern mit ihrem Namen gespeichert sind, müssen Sie diese im Index des Ordners anklicken.

Ein Beispiel aus dem Jahr 2019

 
vor 21 Tagen  
 




HofK
Endlich mal wieder etwas Zeit gefunden um zu programmieren. Da wo ich Ende Juni aufgehört habe geht es weiter. Es fehlte noch die Möglichkeit auch die Kappen mit einer Textur zu versehen. Dazu habe ich ein Update erstellt.

Siehe  [...] 
und  [...] 


<!DOCTYPE html>
<!-- https://discourse.threejs.org/t/profiledcontourgeometry-multimaterial/5801/2 -->
<head>
<title> ProfiledContourGeometryUVs  </title>
<meta charset="utf-8" />
<style>

body {

    margin: 0;

}

</style>
</head>
<body> </body>
<script src="../js/three.min.120.js"></script>
<script src="../js/OrbitControls.120.js"></script>
<script>
'use strict'
// @author hofk
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( -6, 18, 20 );
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const controls = new THREE.OrbitControls( camera, renderer.domElement );
const light = new THREE.DirectionalLight( 0xffffff, 0.6);
light.position.setScalar( 10 );
scene.add( light );
scene.add(new THREE.AmbientLight( 0xffffff, 0.8));
const helper = new THREE.GridHelper( 20, 20);
scene.add( helper );
const detail = 5;
let profileShape1 = [];

for ( let i = detail; i > -1; i -- ){

    profileShape1.push ( 1.75 * Math.cos( 0.7 + i / detail * Math.PI * 2 ), 1.75 * Math.sin( 0.7 + i / detail * Math.PI * 2 ) );

}

const contour1 = [
-3,  4,
0,  4,// here only to show that angle of 180° horizontal works
4,  4,
2,  1,
4, -2,
0, -3,
-4, -3,
-4,  0
];
const profileShape2 = [ -1,1, 1.77,1, 1,-1, -1.4,-1.99 ];
const contour2 = [
2,-2,
2, 0,
4, 4,
9, 4,
9, 2,// here only to show that angle of 180° vertikal works
9, 0,
];
const  tex1 = new THREE.TextureLoader().load('uvgrid01.png' );
const  tex2 = new THREE.TextureLoader().load('beech.jpg' ); // License: free, Non-commercial use
const  tex3 = new THREE.TextureLoader().load('pngwing-com-water.png' );// License:  free, Non-commercial use
//const m0 = new THREE.MeshPhongMaterial( { color: 0xfa0001, side: THREE.DoubleSide } );
//const m1 = new THREE.MeshPhongMaterial( { color: 0xff7b00, side: THREE.DoubleSide } );
//const m2 = new THREE.MeshPhongMaterial( { color: 0xf9f901, side: THREE.DoubleSide } );
const m0 = new THREE.MeshPhongMaterial( { map: tex1, side: THREE.DoubleSide } );
const m1 = new THREE.MeshPhongMaterial( { map: tex2, side: THREE.DoubleSide } );
const m2 = new THREE.MeshPhongMaterial( { map: tex3, side: THREE.DoubleSide } );
//const m3 = new THREE.MeshPhongMaterial( { color: 0x008601, side: THREE.DoubleSide } );
//const m4 = new THREE.MeshPhongMaterial( { color: 0x01bbbb, side: THREE.DoubleSide } );
//const m5 = new THREE.MeshPhongMaterial( { color: 0x250290, side: THREE.DoubleSide } );
const m3 = new THREE.MeshPhongMaterial( { map: tex1, side: THREE.DoubleSide } );
const m4 = new THREE.MeshPhongMaterial( { map: tex3, side: THREE.DoubleSide } );
const m5 = new THREE.MeshPhongMaterial( { map: tex2, side: THREE.DoubleSide } );
//const m6 = new THREE.MeshPhongMaterial( { color: 0xfc4ea5, side: THREE.DoubleSide } );
//const m7 = new THREE.MeshPhongMaterial( { color: 0x83058a, side: THREE.DoubleSide } );
//const m8 = new THREE.MeshPhongMaterial( { color: 0x83058a, side: THREE.DoubleSide } );
const m6 = new THREE.MeshPhongMaterial( { map: tex1, side: THREE.DoubleSide } );
const m7 = new THREE.MeshPhongMaterial( { map: tex2, side: THREE.DoubleSide } );
const m8 = new THREE.MeshPhongMaterial( { map: tex3, side: THREE.DoubleSide } );
const materials = [ m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8, m0, m1, m2, m3, m4, m5, m6, m7, m8 ];
//..................................................... matPerSquare, contourClosed, openEnded );
const frame1 = ProfiledContourUV( profileShape1, contour1, materials, false , false, false );
scene.add( frame1 );
frame1.position.x = -5;
frame1.position.z = 3;
frame1.rotation.y = 2.8;
const frame2 = ProfiledContourUV( profileShape2, contour2, materials, true, false, false );
frame2.position.z = -4;
scene.add( frame2 );
render();

function render() {

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

}

function ProfiledContourUV( profileShape, contour, materials, matPerSquare, contourClosed, openEnded ) {

    // creates group of frame strips, non indexed BufferGeometry
    const len = ( x, y, z ) => Math.sqrt( x * x + y * y + z * z );
    const dot = (x1, y1, z1, x2, y2, z2) => ( x1 * x2 + y1 * y2 + z1 * z2 );
    matPerSquare = matPerSquare!== undefined ? matPerSquare : false;
    contourClosed = contourClosed !== undefined ? contourClosed : true;
    openEnded = openEnded  !== undefined ? ( contourClosed === true ? true : openEnded ) : true;
    if( contourClosed ) contour.push( contour[ 0 ], contour[ 1 ] );
    const hs1 = contour.length / 2;
    const rs1 = profileShape.length / 2;
    const hs = hs1 - 1;// height segments
    const rs = rs1 - 1;// radius segments
    let	vtx = [];// rs1 many vertex colums
    let	frmpos = [];// hs many geometries and meshes
    let	frmuvs = [];// hs many uv's'

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

        vtx.push( [] );
        frmpos.push( [] );
        frmuvs.push( [] );

    }

    vtx.push( [] );// last colum

    if(  !openEnded ) {// for two ends

        frmpos.push( [], [] );// for two ends
        frmuvs.push( [], []  );

    }

    let gFrame = [];// geometries of frame strips
    let frame = [];// meshes of frame strips
    const fGroup = new THREE.Group( );
    let i1, i2, i3, i6, j1, j2;
    let xc0, yc0, xc1, yc1, xc2, yc2, xSh, xDiv;
    let dx, dy, dx0, dy0, dx2, dy2;
    let e0x, e0y,e0Length, e2x, e2y, e2Length, ex, ey, eLength;
    let xd, phi, bend;
    let x, y, z, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
    let x1L, y1L, x2L, y2L, xMin, yMin, xMax, yMax;
    let a, u1, u1a, u1b, u2, u3, u4, v1, v2, v3, d2, d3;
    const epsilon = 0.000001;
    xMin = Infinity;
    yMin = Infinity;
    xMax = -Infinity;
    yMax = -Infinity;

    if( !openEnded ) {

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

            j2 = 2 * j;

            if ( profileShape[ j2 ] < xMin ) xMin = profileShape[ j2 ];

                if ( profileShape[ j2 + 1 ] < yMin ) yMin = profileShape[ j2 + 1 ];

                    if ( profileShape[ j2 ] > xMax ) xMax = profileShape[ j2 ];

                        if ( profileShape[ j2 + 1 ] > yMax ) yMax = profileShape[ j2 + 1 ];

                        }

                    }

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

                        j2 = 2 * j;

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

                            i2 = 2 * i;
                            xc1 = contour[ i2 ];
                            yc1 = contour[ i2 + 1 ];

                            if ( i === 0 ) {

                                xc0 = contour[ ( hs - 1 ) * 2 ];// penultimate point
                                yc0 = contour[ ( hs - 1 ) * 2 + 1 ];

                            } else {

                                xc0 = contour[ i2 - 2 ];// previous point
                                yc0 = contour[ i2 - 1 ];

                            }

                            if ( i === hs ) {

                                xc2 = contour[ 2 ];// second point
                                yc2 = contour[ 3 ];

                            } else {

                                xc2 = contour[ i2 + 2 ];// next point
                                yc2 = contour[ i2 + 3 ];

                            }

                            if ( !contourClosed ) {

                                if ( i === 0 ) {

                                    // direction
                                    dx2 = xc2 - xc1;
                                    dy2 = yc2 - yc1;
                                    // unit vector
                                    e2Length = Math.sqrt( dx2 * dx2 + dy2 * dy2 );
                                    e2x = dx2 / e2Length;
                                    e2y = dy2 / e2Length;
                                    // orthogonal
                                    ex = e2y;
                                    ey = -e2x;

                                }

                                if ( i === hs ) {

                                    // direction
                                    dx0 = xc1 - xc0;
                                    dy0 = yc1 - yc0;
                                    // unit vector
                                    e0Length = Math.sqrt( dx0 * dx0 + dy0 * dy0 );
                                    e0x = dx0 / e0Length;
                                    e0y = dy0 / e0Length;
                                    // orthogonal
                                    ex = e0y;
                                    ey = -e0x;

                                }

                                xDiv = 1;
                                bend = 1;

                            }

                            if ( ( i > 0 && i < hs ) || contourClosed ) {

                                // directions
                                dx0 = xc0 - xc1;
                                dy0 = yc0 - yc1;
                                dx2 = xc2 - xc1;
                                dy2 = yc2 - yc1;

                                if( Math.abs( ( dy2 / dx2 ) - ( dy0 / dx0 ) ) < epsilon ) {// prevent 0

                                    dy0 += epsilon;

                                }

                                if( Math.abs( ( dx2 / dy2 ) - ( dx0 / dy0 ) ) < epsilon ) {// prevent 0

                                    dx0 += epsilon;

                                }

                                // unit vectors
                                e0Length = Math.sqrt( dx0 * dx0 + dy0 * dy0 );
                                e0x = dx0 / e0Length;
                                e0y = dy0 / e0Length;
                                e2Length = Math.sqrt( dx2 * dx2 + dy2 * dy2 );
                                e2x = dx2 / e2Length;
                                e2y = dy2 / e2Length;
                                // direction transformed
                                ex = e0x + e2x;
                                ey = e0y + e2y;
                                eLength = Math.sqrt( ex * ex + ey * ey );
                                ex = ex / eLength;
                                ey = ey / eLength;
                                phi = Math.acos( e2x * e0x + e2y * e0y ) / 2;
                                bend = Math.sign( dx0 * dy2 - dy0 * dx2 );// z cross -> curve bending
                                xDiv = Math.sin( phi );

                            }

                            xSh = profileShape[ j2 ];
                            xd = xSh / xDiv;
                            dx = xd * bend * ex;
                            dy = xd * bend * ey;
                            x = xc1 + dx;
                            y = yc1 + dy;
                            z = profileShape[ j2 + 1 ];// ySh
                            vtx[ j ].push( x, y, z );// store vertex
                            //dApex = xd * Math.cos( phi );

                            if( j === 0 && i === hs && !openEnded ) {//center

                                x1L = xc1;
                                y1L = yc1;

                            }

                            if( j === 0 && i === 0 && !openEnded ) {//center

                                x2L = xc1;
                                y2L = yc1;

                            }

                        }

                    }

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

                        j1 = j + 1;

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

                            i3 = 3 * i;
                            i6 = i3 + 3;
                            x1 = vtx[ j ][ i3 ];
                            y1 = vtx[ j ][ i3 + 1 ];
                            z1 = vtx[ j ][ i3 + 2 ] ;
                            x2 = vtx[ j1 ][ i3 ];
                            y2 = vtx[ j1 ][ i3 + 1 ];
                            z2 = vtx[ j1 ][ i3 + 2 ];
                            x3 = vtx[ j1 ][ i6 ];
                            y3 = vtx[ j1 ][ i6 + 1 ];
                            z3 = vtx[ j1 ][ i6 + 2 ];
                            x4 = vtx[ j ][ i6 ];
                            y4 = vtx[ j ][ i6 + 1 ];
                            z4 = vtx[ j ][ i6 + 2 ];
                            frmpos[ j ].push( x1, y1, z1, x2, y2, z2, x4, y4, z4, x2, y2, z2, x3, y3, z3, x4, y4, z4 );
                            a = len( x4 - x1, y4 - y1, z4 - z1 );
                            d2 = dot( x4 - x1, y4 - y1, z4 - z1, x2 - x1, y2 - y1, z2 - z1 ) / a;
                            d3 = dot( x1 - x4, y1 - y4, z1 - z4, x3 - x4, y3 - y4, z3 - z4, ) / a;

                            if ( d2 >= 0 && d3 >= 0 ) {

                                u1 = 0;
                                u2 = d2 / a;
                                u3 = 1 - d3 / a;
                                u4 = 1;

                            }

                            if ( d2 >= 0 && d3 < 0 ) {

                                u1 = 0;
                                u2 = d2 / ( a - d3 );
                                u3 = 1;
                                u4 = 1 + d3 / ( a - d3 );

                            }

                            if ( d2 < 0 && d3 < 0 ) {

                                u1 = -d2 / ( a - d2 - d3 );
                                u2 = 0;
                                u3 = 1;
                                u4 = 1 + d3 / ( a - d2 - d3  );

                            }

                            if ( d2 < 0 && d3 >= 0 ) {

                                u1 = -d2 / ( a - d2  );
                                u2 = 0;
                                u3 = 1 - d3 / ( a - d2  );
                                u4 = 1;

                            }

                            frmuvs[ j ].push( u1, 1, u2, 0, u4, 1, u2, 0, u3, 0, u4, 1 );

                        }

                    }

                    if( !openEnded ) {

                        dx = xMax - xMin;
                        dy = yMax - yMin;
                        v1 = -yMin / dy;
                        u1a = -xMin / dx;
                        u1b = 1 - u1a;
                        i3 = 3 * hs;

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

                            j1 = j + 1;
                            j2 = 2 * j;
                            x1 = vtx[ j ][ 0 ];
                            y1 = vtx[ j ][ 1 ];
                            z1 = vtx[ j ][ 2 ];
                            x2 = vtx[ j1 ][ 0 ];
                            y2 = vtx[ j1 ][ 1 ];
                            z2 = vtx[ j1 ][ 2 ];
                            frmpos[ rs ].push( x2L, y2L, 0, x1, y1, z1, x2, y2, z2 );
                            u2 = ( profileShape[ j2 ] - xMin ) / dx;
                            v2 = ( profileShape[ j2 + 1 ] - yMin ) / dy;
                            u3 = ( profileShape[ j2 + 2 ] - xMin ) / dx;
                            v3 = ( profileShape[ j2 + 3 ] - yMin ) / dy;
                            frmuvs[ rs ].push( u1a, v1, u2, v2, u3, v3 );
                            x1 = vtx[ j1 ][ i3 ];
                            y1 = vtx[ j1 ][ i3 + 1 ];
                            z1 = vtx[ j1 ][ i3 + 2 ] ;
                            x2 = vtx[ j ][ i3 ];
                            y2 = vtx[ j ][ i3 + 1 ];
                            z2 = vtx[ j ][ i3 + 2 ];
                            frmpos[ rs1 ].push( x1L, y1L, 0, x1, y1, z1, x2, y2, z2 );
                            u2 = 1 - ( profileShape[ j2 + 2 ] - xMin ) / dx;
                            v2 = ( profileShape[ j2 + 3 ] - yMin ) / dy;
                            u3 = 1 - ( profileShape[ j2 ] - xMin ) / dx;
                            v3 = ( profileShape[ j2 + 1 ] - yMin ) / dy;
                            frmuvs[ rs1 ].push( u1b, v1, u2, v2, u3, v3 );

                        }

                    }

                    for ( let j = 0; j < ( openEnded ? rs : rs + 2 ); j ++ ) {

                        gFrame[ j ] = new THREE.BufferGeometry( );
                        gFrame[ j ].setAttribute('position', new THREE.BufferAttribute( new Float32Array( frmpos[ j ] ), 3 ) );
                        gFrame[ j ].setAttribute('uv', new THREE.BufferAttribute( new Float32Array( frmuvs[ j ] ), 2 ) );

                        if ( matPerSquare ) {// MultiMaterial support (for each square)

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

                                gFrame[ j ].addGroup( i * 6, 6, j * hs + i );

                            }

                            frame[ j ] = new THREE.Mesh( gFrame[ j ], materials );

                        } else {// material per frame strip

                            frame[ j ] = new THREE.Mesh( gFrame[ j ], materials[ j ] );

                        }

                        gFrame[ j ].computeVertexNormals( );
                        fGroup.add( frame[ j ] )

                    }

                    return fGroup;// group of frame strips

                }

                </script>
                </html>
 
vor 11 Tagen  
 




HofK
Auch die Version im Addon THREEg.js wurde geupdated und beherrscht die Deckel mit Textur.  [...] 
 
vor 9 Tagen  
 




p.specht
Perfekt! Bald kommt ein Angebot von Google oder AutoCAD. Deren Strategie ist ja das Aufkaufen potentieller Konkurrenten
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen...
vor 9 Tagen  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

102.572 Betrachtungen

Unbenanntvor 0 min.
Manfred BareiVorgestern (20:52)
Wilfried Friebe vor 5 Tagen
iF vor 5 Tagen
RudiB. vor 5 Tagen
Mehr...

Themeninformationen



AGB  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Impressum  |  Mart  |  Support  |  Suche

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