PHP, HTML & JavaScript- Forum | | | | - Seite 1 - |
| HofK | Auf einen heißen Tipp von IF hin, habe ich mir mal three.js [...] angeschaut. Da [...] (ganz unten) die ersten Resultate. |
| | | | |
| | | | - Seite 35 - |
| | p.specht
| Wird es auch dynamische Objekte (Deckenventilator, Vorhang im Wind, Stubenfliege) geben? (Ein Narr kann ja mehr fragen, als 10 Weise beantworten...) |
| | | Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 01.06.2020 ▲ |
| |
| | HofK | | | | | |
| | p.specht
| WOW ! |
| | | XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 03.06.2020 ▲ |
| |
| | HofK | Da ich gerade dabei bin Texturen für die Rahmen zu ermöglichen, d.h. die uv Werte zu berechnen, habe ich mal nach fertigen Texturen geschaut. Zumal meine künstlerischen (Wand selbst gemalert!) und fotografischen Fähigkeiten eher begrenzt sind.
Die Software sweethome3d [...] bietet Modelle und Texturen zum Download. Lizenz beachten!
Etwas Buche für die 3D-Fensterbank, eine Türimitation (Textur, nicht 3D!) und eine Treppe (3D .obj Datei mit .mtl), die noch etwas sinnlos im Raum steht, machen den Raum etwas "gemütlicher". Da kann man sich bei Bedarf richtig austoben!
|
| | | | |
| | HofK | Mit den Texturen für die Rahmen dauert es jetzt etwas länger. Man sollte angefangene Arbeiten nicht mehr als ein Jahr liegen lassen. Zumal, wenn man die Ansätze/Herleitungen so salopp wie ich macht. Konnte gerade noch einen A5-Zettel aus dem Stapel fischen, auf dem einige Winkel, Strecken und Formeln stehen. Wenn man das nicht selbst in Form einer ordentlichen Anleitung für andere Personen schreibt, sieht man selbst nach einiger Zeit nicht mehr sofort klar. Auch meine Programm-Kommentare sind eher sehr knapp.
Man staunt, was man da erdacht hat und lernt es fast wie neu.
Aber ich bin optimistisch. Das ist zwar noch nicht korrekt, aber ein Anfang.
Man muss mit Hilfe der Winkel Seiten der im Bild erkennbaren Dreiecke (nicht ordentlich in der Textur) berechnen und dann im Verhältnis zur längsten Seite die entsprechenden Abschläge für den u-Wert an allen vier Ecken machen.
Der v-Wert ist sehr einfach nur 0 bzw. 1, da die Profile stets parallele Kanten haben.
Für das erste und letzte Segment braucht es eine extra Fallunterscheidung. |
| | | | |
| | HofK | HofK (08.06.2020)
Für das erste und letzte Segment braucht es eine extra Fallunterscheidung.
Es ist einfacher als angenommen, eine Fallunterscheidung ist dafür nicht nötig. Es gibt insgesamt nur vier Fälle. Die Berechnung selbst ist auch recht elementar. Ich hatte anfangs wieder mal viel zu kompliziert gedacht.
Die Lösung beruht auf der Berechnung der Projektion eines Vektors auf einen anderen Vektor. Interaktiv kann man das z.B. dort ausprobieren. [...]
Man speichert die vier Eckpunkte 1.. 4 und berechnet dann die Länge des Vektors v14. Die über ein Rechteck hinausgehenden bzw. fehlenden Strecken sind gerade die Projektion, die man mit dem Skalarprodukt ( Punktprodukt / dot product ) und dieser Länge errechnet.
frmpos[ j ].push( x1, y1, z1, x2, y2, z2, x4, y4, z4, x2, y2, z2, x3, y3, z3, x4, y4, z4 );// positions
a = len( x4 - x1, y4 - y1, z4 - z1 );// length v14
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 );// uv's'
|
| | | | |
| | p.specht
| Meister! |
| | | XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 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>
|
| | | | |
| | 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.
In der obigen Variante mit der eigenständigen Funktion wird die Definition der Gruppe innerhalb der Funktion erledigt.
|
| | | | |
| | p.specht
| Schaffen ältere Computer das? Langsam wird die Sache vielleicht zu abhängig vom Einsatz teurer Grafikkarten... |
| | | XProfan 11Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'... | 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. |
| | | | |
| | 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. |
| | | | |
|
AntwortenThemenoptionen | 333.486 Betrachtungen |
ThemeninformationenDieses Thema hat 10 Teilnehmer: |