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



HofK
Soeben habe ich die alpha Version mit Skalierung auf  [...]  gebracht. Auf  [...]  ist ein Video erneuert.

Für die Halbkugeln ist die Skalierung zwischen Start- und Endfunktion möglich.

Für die Kugel klappt die Skalierung aber nur zwischen den Standardwerten 0 und 1.

Einige Versuche mit Start- und Endfunktion führten zu immer unterschiedlichen Fehlpositionierungen. Dabei reagieren konvexe und konkave Funktionen unterschiedlich. Wenn die Abende jetzt wieder länger werden, muss ich da mal tiefer in die mathematische Theorie eintauchen. Eventuell gibt es eine simple Lösung - muss man nur finden.

Im Quelltext sind Teile der Versuche noch sichtbar, weil ich da eventuell wieder ansetze. 

Momentan verfügbare Funktionen:

// u azimuth (start: x axis, counterclockwise)
// for hemispheres: v polar (start: pole 0, end: equator 1), t time

stretchSouth,//function ( u, v, t )// stretch / compress south hemisphere in -y direction
stretchNorth, //function ( u, v, t )// stretch / compress north hemisphere in +y direction
endPole,//function ( u, t )// end angle ( to equator, per phi)
startPole, //function ( u, t )// start angle ( from south- or north pole, per phi)
scalePoleH,//function ( v, t )// scaling hemispheres from pole to equator ( is overwritten by scalePole )

// for sphere: v polar (start: south pole 0, end: north pole 1), t time

rAzimuthPole, //function ( u, v, t )// radius depending on location,
equatorGap,//function ( u, t )// gap in relation to the radius
squeeze,// function ( u, t )// 0 sphere to 1 flat circle
moveX,//function ( u, v, t )// factor for radius, move in x direction
moveY,//function ( u, v, t )// factor for radius, move in y direction
moveZ,//function ( v, u, t )// factor for radius, move in z direction

endAzimuth,//function ( v, t )// end azimuth angle phi (per theta)
startAzimuth,//function ( v, t )// starting azimuth angle phi (per theta)
scaleAzimuth,//function ( u, t )// scaling between start and end of azimuth angle ( phi 0 .. 2*PI)

scalePole, //function ( v, t )// scaling between start and end of polar angle (theta -PI/2 .. PI/2 )

materialSouth,//function ( u, v, t )// material South
materialNorth,//function ( u, v, t )// material North
materialPlane,//function ( u, t )// material of extra south top or north bottom
materialWedge,//function ( v, t )// material wedge side
 
18.10.2017  
 




HofK
Bei der Positionierung der singulären Pole und Mittelpunkte von Boden und Deckel gab es noch Fehler im Zusammenhang mit der Anwendung der Funktionen.

Das Problem steckt in den Kugelkoordinaten. Die Pole haben zwar eindeutig einen Polwinkel theta ( -Pi/2, +Pi/2), aber da sie normal mittig liegen keinen bestimmten Azimut phi.

Bei der Berechnung mit Funktionen die u (und damit phi) als Argument haben, gibt es dann Probleme - unsinnige Ergebnisse.

Deshalb berechne ich einen sehr kleinen Kreis um die Mittelpunkte (x und z) und nehme den Mittelwert. Dazu muss, auch wenn nur einige Kugelkeile gewünscht werden, dort leider der vollständige Kreis geschlossen werden. Das erhöht die Auswahlabfragen, ist aber nicht zu vermeiden.

So gibt es nun aber auch in solchen Fällen sinnvolle Ergebnisse.
Auf  [...]  ist die Version aktuell.

Die Berechnung geschieht im Zusammenspiel der Funktionen
function setPoleVertex( south_north )
function setVertex( south_north )
function setPlaneCenterVertex( south_north )






 
21.10.2017  
 




HofK
Zwischendurch mal etwas Abwechslung.

Auf die Frage eines etwas hilflosen Anfängers hin  [...]  habe ich mein etwas älteres Beispiel zu raycast überarbeitet. Die deutschsprachigen Variablen Englisch ausgedrückt und die Kommentare wo sinnvoll übersetzt. Dazu noch eine Erweiterung zum besseren Verständnis des etwas schwierigen three.js Sachverhalts: Der Strahl kann dargestellt werden.  [...] 



Die alte Version bleibt erhalten.  [...] 

-----

Weiterhin ist THREEf auf Revision 87 umgestellt,  [...]  und enthält nun auch den vertexFaceNumbersHelper

Die Änderung zu r87 betrifft flatShading:

flatShading =document.getElementById( "flatShading" ).checked;

//shading =flatshading ? THREE.FlatShading : THREE.SmoothShadig; // old
//.flatShading: true or false; // three.js r87


Also sehr einfach als Eigenschaft nur true oder false.

Beim Test habe ich eben festgestellt, dass die Sandbox nun auch auf Opera 48.0.2685.50 (PGO) und Chrome 61.0.3163.100 läuft! Hatte ich nicht mehr erwartet. Kann ich den Hinweis auf Firefox wohl löschen.

Auf GitHub muss THREEf noch erneuert werden. 
 
24.10.2017  
 




HofK
HofK (18.10.2017)
... Wenn die Abende jetzt wieder länger werden, muss ich da mal tiefer in die mathematische Theorie eintauchen. Eventuell gibt es eine simple Lösung - muss man nur finden. ...



Es bedurfte keiner tieferen mathematischen Forschungen. Die Lösung ist ganz einfach und fast so wie ich es schon hatte. Wenn man aber einen kleinen Fehler nicht bemerkt und in alle Varianten wieder mit einbaut, sieht es dunkel aus.
Irgendwann kam die Erleuchtung, ich kann ziemlich hartnäckig sein.
Die Anzahl der Fehlversuche ist nicht veröffentlichungsfähig - hab auch nicht mitgezählt.

Und so einfach geht es:

In der Funktion create():
if ( g.scaleH ) {

    //  ...HSE Hemisphere Start- End
    g.scalePoleHSE = function( u, v, t ) { return  1 - ( g.startPole( u, t ) + ( g.endPole( u, t ) - g.startPole(u, t ) ) * g.scalePoleH( v, t ) ) }

} else {

    // uses the decomposed scale function (South and North)
    g.scalePoleS = function( u, v, t ) { return 2 * ( g.startPole( u, t ) + ( g.endPole( u, t ) - g.startPole( u, t ) ) * g.scalePole(  v / 2, t ) ) }
    g.scalePoleN = function( u, v, t ) { return 2 * ( 1 - g.endPole( u, t ) + ( g.endPole( u, t ) - g.startPole( u, t ) ) * ( 1 - g.scalePole( 1 -  v / 2, t ) ) ) }

}


und dann in morphVertices( time ) die Berechnung des passenden Polwinkels theta .
if ( g.scaleH )  {

    // scaling between pole and equator (start- and endPole) per hemisphere --> south is like north
    theta = south_north * pi2 * g.scalePoleHSE( nji, nih, t );

} else {

    // scaling of the sphere between south and north (start- and endPole) with decomposed function
    theta = south_north * pi2 * ( 1 - ( south_north === SOUTH ? g.scalePoleS( nji, nih, t ) : g.scalePoleN( nji, nih, t ) ) );

}


In der Sandbox  [...]  jetzt verfügbar, und dort  [...]  momentan aktuelles Video 4.

 
28.10.2017  
 




HofK
Da mit indexed BufferGeometry nun wesentliche Sachen in THREEp funktionieren, bin ich dabei die sogenannte Dreieckssuppe, non indexed Buffer Geometry anzugehen.

Manch einer stürzt sich als Hobby auf riesige Puzzle, ich erzeuge mir ein systematisches Durcheinander und zwänge es dann per JavaScript in die benötigte Ordnung.



Mein Vorteil jetzt bei der zweiten Geometrie-Variante ist, dass ich anhand der ersten Variante sehr schnell die Korrektheit prüfen kann. So ist noch keine Grafik zu sehen, da nur create() existiert und die Positionen noch nicht berechnet sind, aber anhand einer Kontrollausgabe sieht man, dass es stimmt.



Berechnet werden die zu einem nur virtuell existierendem vertex gehörenden faces und die jeweilige Ecke a,b oder c des Dreiecks.

Natürlich gibt es wieder Indexrechnungen ( fIdx - face index) wo man sich muss.


if ( j === 0 ) {

if( i > bottomS ) {
fIdx = uWed * ( i - 1 ) * ( i - 1 ) + w * ( 2 * ( i - 1 ) + 1 ) - uWed * bottomS * bottomS;
...
if( i < topS ) {
fIdx = uWed * i * i + w * ( 2 * i + 1 ) - uWed * bottomS * bottomS;

----

if ( j > 0 ) {

if( i > bottomS ) {
fIdx = uWed * ( i - 1 ) * ( i - 1 ) + w * ( 2 * ( i - 1 ) + 1 ) + 2 * ( j - 1 ) - uWed * bottomS * bottomS;
...
if( i < topS ) {
fIdx = uWed * i * i + w * ( 2 * i + 1 ) + 2 * j - 1 - uWed * bottomS * bottomS;

----

if ( w === uWed - 1) {

if( i > bottomS ) {
fIdx = uWed * ( i - 1 ) * ( i - 1 ) + w * ( 2 * ( i - 1 ) + 1 ) + 2 * ( i - 1 ) - uWed * bottomS * bottomS;
...
if( i < topS ) {
fIdx = uWed * i * i + w * ( 2 * i + 1 ) + 2 * i - 1 - uWed * bottomS * bottomS;


Mit

fPos = fIdx * 9;

vFace.push( fPos );
vPos.push( fPos + b );

fIdx ++;


werden die ermittelten Werte gespeichert. Hier im Beispiel die Ecke b (Konstante 3, drei Koordinatenwerte je Punkt) für die Position. Das hängt von der jeweiligen Anfangsecke und dem Drehsinn (Süd/ Nord unterschiedlich) ab und entspricht der Anordnung bei indexedBufferGeometry.

Dazu gibt es wieder ein "Konstruktionsblatt".

 
01.11.2017  
 




HofK
Zwischendurch mal etwas Abwechselung bei der Indexfummelei.

In einfachem Englisch gestellte Fragen verstehe ich, und so konnte ich dort [...] 

eventuell etwas weiterhelfen.

Dazu habe ich nur ein vorhandenes Beispiel leicht verändert und Englisch gemacht.



Es kann unter  [...]  etwas weiter unten (bei Knoten) ausprobiert werden.
<!doctype html>
<html lang="de">
<head>
<title> picture ball </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script src="../js/three.min.87.js"></script>
<script src="../js/OrbitControls.js"></script>
<script src="../js/THREEx.WindowResize.js"></script>
<div id="threejs" style="position: absolute; left:0px; top:0px"></div>
</body>
<script>
var boards = [];
var texture = [];
var matTexture = [];
init();
animate();
//...........................

function init() {

    scene  = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 45, window.innerWidth/ window.innerHeight,1, 300000 );
    scene.add( camera );
    camera.position.set( 0, 1500, 5000 );
    renderer = new THREE.WebGLRenderer( { antialias:true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor( 0xeeeeee );
    container = document.getElementById('threejs' );
    container.appendChild( renderer.domElement );
    THREEx.WindowResize( renderer, camera );
    controls = new THREE.OrbitControls( camera, renderer.domElement );
    texture[0] = new THREE.TextureLoader().load( "waterlily.png" );
    texture[1] = new THREE.TextureLoader().load( "dahlia.jpg" );
    texture[2] = new THREE.TextureLoader().load( "petunia.jpg" );
    texture[3] = new THREE.TextureLoader().load( "frog.jpg" );

    for (var z = 0; z < 4; z++) {

        matTexture[z] = new THREE.MeshBasicMaterial( { color:0xffdd99, map: texture[z], transparent:true, opacity:0.8, wireframe:false} );

    }

    // ball
    materialSph = new THREE.MeshBasicMaterial( { color: 0x0099dd, transparent: true, opacity: 0.8, wireframe:false } );
    sphGeo  = new THREE.SphereGeometry(1200, 8, 8);
    sphere = new THREE.Mesh( sphGeo, materialSph );
    scene.add( sphere );
    // board for some things
    materialBoard   = new THREE.MeshBasicMaterial({color:0xdddddd, transparent:true, opacity:0.4, wireframe: true });
    boardGeo  = new THREE.PlaneGeometry(500,500);
    picGeo = new THREE.PlaneGeometry( 200, 200 );

    for (var i = 0; i < sphGeo.vertices.length; i++)	{

        board = new THREE.Mesh( boardGeo, materialBoard );// board for pictures etc.
        pic = new THREE.Mesh( picGeo, matTexture[ i % 4 ] );
        board.add( pic ) ;//  add picture to the board
        pic.position.x = -70;// position on the board
        pic.position.y = 120;
        boards.push( board );
        scene.add( boards[ i ] );
        boards[ i ].position.set( 1.3 * sphGeo.vertices[ i ].x , 1.3 * sphGeo.vertices[ i ].y, 1.3 * sphGeo.vertices[ i ].z );

    }

}

function animate() {

    requestAnimationFrame( animate );

    for( var n = 0; n < boards.length; n ++ ) {

        boards[ n ].lookAt( camera.position );
        // or see https://discourse.threejs.org/t/add-marker-to-rotating-globe-object-help/1116/6
        // boards[ n ].quaternion.copy( camera.quaternion );

    }

    renderer.render( scene, camera );
    controls.update();

}

</script>
</html>
 
03.11.2017  
 




HofK
Kleiner Nachschlag zur discourse.threejs.org Hilfe (s.o.)  [...] 


<!doctype html>
<html lang="de">
<head>
<title> picture coil </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script src="../js/three.min.87.js"></script>
<script src="../js/OrbitControls.js"></script>
<script src="../js/THREEx.WindowResize.js"></script>
<!--  https://github.com/hofk/THREEf.js/blob/master/THREEf_87/THREEf.js -->
<script src="../js/THREEf.js"></script>
<div id="threejs" style="position: absolute; left:0px; top:0px"></div>
</body>
<script>
var boards = [];
var texture = [];
var matTexture = [];
init();
animate();
//...........................

function init() {

    scene  = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth/ window.innerHeight,1, 100000 );
    scene.add( camera );
    camera.position.set( -200, 500, 12000 );
    renderer = new THREE.WebGLRenderer( { antialias:true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor( 0xeeeeee );
    container = document.getElementById('threejs' );
    container.appendChild( renderer.domElement );
    THREEx.WindowResize( renderer, camera );
    controls = new THREE.OrbitControls( camera, renderer.domElement );
    texture[0] = new THREE.TextureLoader().load( "waterlily.png" );
    texture[1] = new THREE.TextureLoader().load( "dahlia.jpg" );
    texture[2] = new THREE.TextureLoader().load( "petunia.jpg" );
    texture[3] = new THREE.TextureLoader().load( "frog.jpg" );

    for (var z = 0; z < 4; z++) {

        matTexture[z] = new THREE.MeshBasicMaterial( { map: texture[z], transparent:true, opacity:0.8, wireframe:false} );

    }

    // coil generated with addon THREEf.js
    var geometry = new THREE.Geometry();
    geometry.createMorphGeometry = THREEf.createMorphGeometry;// insert the methode from THREEf.js
    // apply the methode with some parameters

    geometry.createMorphGeometry({

        radius: 200,
        height: 600,
        radiusSegments: 18,
        heightSegments: 80,
        withBottom: true,
        withTop: true,
        centerX: function ( v, t ) { return 2 * Math.sin( 6 * Math.PI * v ) },
        centerY: function ( v, t ) { return v * ( v + 10 ) },
        centerZ: function ( v, t ) { return 2 * Math.cos( 6 * Math.PI * v ) }

    });

    var material = new THREE.MeshBasicMaterial( { color: 0x0099dd, transparent: true, opacity: 0.8, wireframe:false } );
    var mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
    // board for some things
    materialBoard   = new THREE.MeshBasicMaterial({color:0xdd00dd, transparent:true, opacity:0.5, wireframe: false });
    boardGeo  = new THREE.PlaneGeometry(500,500);
    picGeo = new THREE.PlaneGeometry( 160, 160 );
    idx = 0;

    for (var i = 0; i < geometry.vertices.length; i++)	{

        if ( i % 32 === 0) {

            board = new THREE.Mesh( boardGeo, materialBoard );// board for pictures etc.
            pic1 = new THREE.Mesh( picGeo, matTexture[ idx % 4 ] );
            pic2 = new THREE.Mesh( picGeo, matTexture[ ( idx % 4 ) % 2 ] );
            board.add( pic1 );//  add picture to the board
            board.add( pic2 );
            pic1.position.x = -70;// position on the board
            pic1.position.y = 120;
            pic1.position.z = 20;
            pic2.position.x = 80;
            pic2.position.y = -120;
            pic2.position.z = 20;
            boards.push( board );
            scene.add( boards[ idx ] );
            boards[ idx ].position.set( 1.4 * geometry.vertices[ i ].x ,  geometry.vertices[ i ].y + 300, 1.4 * geometry.vertices[ i ].z );
            idx ++;

        }

    }

}

function animate() {

    requestAnimationFrame( animate );

    for( var n = 0; n < boards.length; n ++ ) {

        boards[ n ].quaternion.copy( camera.quaternion );

    }

    renderer.render( scene, camera );
    controls.update();

}

</script>
</html>

-----------------------------------------------------------------------------------------

Bei meiner Indexrechnerei hat mich eine falsch gesetzte Klammer aufgehalten. Ständig darüber hinweg gelesen und lange nicht entdeckt. Das Ergebnis war nur in bestimmten Konstellationen falsch.



offensichtlich nicht korrekt



nun klappt es aber
 
08.11.2017  
 




p.specht

Wow!
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'...
08.11.2017  
 




HofK
Habe soeben den "Buddelkasten" auf den neuesten Stand gebracht.  [...]  In ihm kann man jetzt auch Gebilde aus der three.js "Dreieckssuppe" non indexed BufferGeometry erzeugen.

Auf dem Weg dahin war das uv Mapping einmal "eigen".
Da kommt die Frage auf "Bug oder Feature?"



Manche Fehler sind einfach so "schön", dass man etwas daraus machen kann.

Noch fehlt bei non indexed die Berechnung der Normalen, bei indexed wird da momentan die three.js interne Funktion benutzt. Sie führt aber zu unschönen Nähten und muss auch noch ersetzt werden. Das gibt wieder eine ausgiebige Rechnerei wie bei THREEf.
 
10.11.2017  
 




Georg
Teles
In Sachen Grafik bin ich eine Niete aber verfolge den Thread schon länger und die Beispiele lassen echt viel Spielerei übrig, da kann ich auch nur staunen genial !
 
XProfan X3
TC-Programming [...] 
XProfan 8.0 - 10.0 - X2 - X3 - X4

11.11.2017  
 




HofK
Georg Teles (11.11.2017)
In Sachen Grafik bin ich eine Niete ...


Meine Fähigkeiten bei Grafik sind auch eher bescheiden, hier wird nur etwas dreidimensionales Denken, etwas Mathematik in Form von 3D Geometrie und ein wenig dreidimensionales Rechnen (Vektorrechnung) benötigt. Und dann die Datenfelder mit den schönen Indexrechnereien.

Entscheidend ist die zugrunde liegende Bibliothek three.js, die die 3D Web-Grafik webGL erst handhabbar macht.

___________________________________________________

Die Berechnung der Normalen ging schneller als angenommen, da ich recht einfach von THREEf kopieren konnte und nur einige Änderungen anstanden.

Auch die Nähte sind schon fast weg. Im Bild erkennbar, dass am Äquator keine Naht sichtbar ist und an der Schnittstelle erster/letzter Keil nur noch auf der Nordhalbkugel.



Die Nahtglättung ist noch halbwegs überschaubar.
// mean of equator normals, prevents a seam

if ( g.bottom < eqt && g.top > eqt ) {

    for ( var vS = g.southTopVertex, vN = g.northBottomVertex; vS >= g.southTopVertex - eqt * uWed ; vS --, vN -- ) {

        nX = ( g.normals[ g.vertexPositions [ vS ][ 0 ] ] + g.normals[ g.vertexPositions [ vN ][ 0 ] ] ) / 2;
        nY = ( g.normals[ g.vertexPositions [ vS ][ 0 ] + 1 ] + g.normals[ g.vertexPositions [ vN ][ 0 ] + 1 ] ) / 2;
        nZ = ( g.normals[ g.vertexPositions [ vS ][ 0 ] + 2 ] + g.normals[ g.vertexPositions [ vN ][ 0 ] + 2 ] )  / 2;

        for ( var f = 0; f < g.vertexFaces[ vS ].length; f ++ ) {

            g.normals[ g.vertexPositions[ vS ][ f ] ] = nX;
            g.normals[ g.vertexPositions[ vS ][ f ] + 1 ] = nY;
            g.normals[ g.vertexPositions[ vS ][ f ] + 2 ] = nZ;

        }

        for ( var f = 0; f < g.vertexFaces[ vN ].length; f ++ ) {

            g.normals[ g.vertexPositions[ vN ][ f ] ] = nX;
            g.normals[ g.vertexPositions[ vN ][ f ] + 1 ] = nY;
            g.normals[ g.vertexPositions[ vN ][ f ] + 2 ] = nZ;

        }

    }

}

// sometimes mean value of the normals of start and end wedge, prevents a seam

if ( wed === uWed ) {

    if ( g.bottom < eqt ) {

        wL = g.wedgeSouthEndIdx.length;
        // console.log( " wL " + wL ); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        for ( var wIdx = 0; wIdx < wL; wIdx ++ ) {

            x1 = g.positions[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ 0 ] ];
            y1 = g.positions[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ 0 ] + 1 ];
            z1 = g.positions[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ 0 ] + 2 ];
            // console.log( " wIdx " + wIdx + " : " +  x1 + ", " +  y1 + ", " +  z1 ); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            x2 = g.positions[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ 0 ] ];
            y2 = g.positions[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ 0 ] + 1 ];
            z2 = g.positions[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ 0 ] + 2 ];

            if ( Math.sqrt( ( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) + ( z2 - z1 ) * ( z2 - z1 ) ) < 0.0001 ) {

                nX1 = g.normals[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ 0 ] ];
                nY1 = g.normals[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ 0 ] + 1 ];
                nZ1 = g.normals[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ 0 ] + 2 ];
                nX2 = g.normals[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ 0 ] ];
                nY2 = g.normals[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ 0 ] + 1 ];
                nZ2 = g.normals[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ 0 ] + 2 ];
                nX = ( nX1 + nX2 ) / 2;
                nY = ( nY1 + nY2 ) / 2;
                nZ = ( nZ1 + nZ2 ) / 2;

                for ( var f = 0; f < g.vertexFaces[ g.wedgeSouthEndIdx[ wIdx ] ].length; f ++ ) {

                    g.normals[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ f ] ] = nX;
                    g.normals[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ f ] + 1 ] = nY;
                    g.normals[ g.vertexPositions[ g.wedgeSouthEndIdx[ wIdx ] ][ f ] + 2 ] = nZ;
                    g.normals[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ f ] ] = nX;
                    g.normals[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ f ] + 1 ] = nY;
                    g.normals[ g.vertexPositions[ g.wedgeSouthStartIdx[ wL - wIdx - 1 ] ][ f ] + 2 ] = nZ;

                }

            }

        }

    }

}


if (g.top > eqt) fehlt noch. Ebenso eine Prüfung auf optimierbarkeit der Zeilen.


Fünf mal } am Ende sind nicht gerade übersichtlich, da bieten sich dann abschließende Kommentare an. (Im Gesamtprogramm sind es hier dann 7 Klammern!) Durch die Faltung des Codes im Editor behält man (meistens) aber noch den Überblick. 
 
12.11.2017  
 




HofK
Nachdem auch die letzte Naht geglättet war, fiel mir ein, dass ich vorhatte bei non indexed BufferGeometry eine Explosionsdarstellung zu probieren.

Und das funktioniert dank der vorhandenen Daten denkbar einfach.

Da ich zur Berechnung der Vertex-Normalen die Normalen der Dreiecke (faces) benötigte, sind diese im Datenfeld g.faceNormals abgespeichert.

Addiert man nun zu jeder Ecke (vertex - Ortsvektor) ein Vielfaches dieser Dreiecks-Normalen, so treibt es die Dreiecke von der Mitte her auseinander.





Da die Dreiecke von Boden, Deckel und Keil identische Normalen haben (parallel!) werden sie gleichartig verschoben und bleiben so zusammen.

Man kann das nun auch in der Sandbox  [...]  ausprobieren. Die Funktion explode wirkt natürlich nur mit non indexed und nimmt lediglich den Zeitparameter t entgegen.
// explode

if ( !g.explodeDefault ) {

    for ( var f = 0; f < g.faceCount; f ++ ) {

        for ( var p = 0; p < 3; p ++ ) {

            g.positions[ f * 9 + p * 3 ] = g.positions[ f * 9 + p * 3 ] + g.faceNormals[ f * 3 ] * g.radius *  g.explode( t );
            g.positions[ f * 9 + p * 3 + 1 ] = g.positions[ f * 9 + p * 3 + 1 ] + g.faceNormals[ f * 3 + 1 ] * g.radius * g.explode( t );
            g.positions[ f * 9 + p * 3 + 2 ] = g.positions[ f * 9 + p * 3 + 2 ] + g.faceNormals[ f * 3 + 2 ] * g.radius * g.explode( t );

        }

    }

}


THREEp arbeitet nun mit der neuesten Revision 88 von three.js zusammen. Für THREEf werde ich explode nachrüsten.
 
14.11.2017  
 




Antworten


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

332.643 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