55 < title > t</ title >
66 < meta charset ="utf-8 ">
77 < meta name ="viewport " content ="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0 ">
8- <!-- <link type="text/css" rel="stylesheet" href="main.css"> -->
98 < style >
109 html , body {
1110 margin : 0 ;
@@ -43,6 +42,8 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
4342 </ option >
4443 < option value ="ganesha.glb "> Ganesha Cologne Zoo - https://codeforcologne.github.io/Denkmal-4D-Koeln/
4544 </ option >
45+ < option value ="AnimatedMorphCube.glb "> AnimatedMorphCube - KhronosGroup Models Testing</ option >
46+ < option value ="animated_tectonic_plates_collide_loop.glb "> tectonic plates Animated - CC-BY-SA Syafani</ option >
4647 < option value ="Avocado.glb "> Avocado - KhronosGroup Models Testing</ option >
4748 < option value ="BarramundiFish.glb "> BarramundiFish - KhronosGroup Models Testing</ option >
4849 < option value ="LightsPunctualLamp.glb "> LightsPunctualLamp - KhronosGroup Models Testing</ option >
@@ -57,20 +58,21 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
5758 https://codeforcologne.github.io/Denkmal-4D-Koeln/</ option >
5859 < option value ="grinkopf_opt.glb "> Grinkopf Cologne - Optimized with gltf-transform
5960 https://codeforcologne.github.io/Denkmal-4D-Koeln/</ option >
60- < option value ="coffeemat.glb "> coffeemat with KTX2 cpmpression - KhronosGroup Models Testing</ option >
61+ < option value ="coffeemat.glb "> coffeemat with KTX2 cpmpersion - KhronosGroup Models Testing</ option >
6162 </ optgroup >
6263 </ select >
6364 < button id ="uploadButton "> Upload a file</ button >
6465 < p > Only simple GLB Models and KTX2 commpersion is supported</ p >
65-
66-
67-
6866 </ div >
67+
6968 < script src ="https://code.jquery.com/jquery-3.7.1.min.js "
7069 integrity ="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo= " crossorigin ="anonymous "> </ script >
7170 < script src ='./lib/three/three_all_in.js '> </ script >
7271
7372 < script >
73+ // animation
74+ let mixer = null ;
75+ let clock = new THREE . Clock ( ) ;
7476
7577 document . getElementById ( 'uploadButton' ) . addEventListener ( 'click' , function ( ) {
7678 loadFileViaFileAPI ( ( contents , fileName ) => {
@@ -89,7 +91,7 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
8991 function loadFileViaFileAPI ( callback ) {
9092 const input = document . createElement ( 'input' ) ;
9193 input . type = 'file' ;
92- input . accept = '.stl,.glb' ; // Adjust file types as needed
94+ input . accept = '.stl,.glb' ;
9395
9496 input . onchange = function ( event ) {
9597 const file = event . target . files [ 0 ] ;
@@ -114,8 +116,6 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
114116 input . click ( ) ;
115117 }
116118
117-
118-
119119 function loadSelection ( ) {
120120 var selection = document . getElementById ( "selection" ) . value ;
121121 if ( selection . indexOf ( 'glb' ) > - 1 ) {
@@ -128,25 +128,16 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
128128 }
129129 }
130130
131- /*
132- window.THREE = require( './lib/three/three.js' );
133- */
134-
135- // let modeltype = 'glb';
136131 let modeltype = 'stl' ;
137132
138133 function ThreeD ( viewer ) {
139134 THREE . Cache . enabled = true ;
140135 this . viewer = viewer ;
141- // this.progressBar = viewer.ui.panel.progressBar;
142- // this.$container = viewer.ui.canvas.$imageDiv;
143136 }
144137
145138 const TD = ThreeD . prototype ;
146139
147-
148140 TD . init = function ( model , source ) {
149-
150141 this . modeltype = modeltype ;
151142
152143 if ( document . getElementById ( 'container' ) ) {
@@ -158,6 +149,7 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
158149 container . id = 'container' ;
159150 document . body . appendChild ( container ) ;
160151 const dimensions = this . getDimensions ( ) ;
152+
161153 // renderer
162154 this . renderer = new THREE . WebGLRenderer ( { antialias : true } ) ;
163155 this . renderer . setClearColor ( 0x222222 ) ;
@@ -166,8 +158,10 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
166158 this . renderer . shadowMap . enabled = true ;
167159 document . getElementById ( 'container' ) . appendChild ( this . renderer . domElement ) ;
168160 this . manager = new THREE . LoadingManager ( ) ;
161+
169162 // camera
170163 this . camera = new THREE . PerspectiveCamera ( 60 , dimensions . ratio ) ;
164+
171165 // controls
172166 this . controls = new THREE . TrackballControls ( this . camera , this . renderer . domElement ) ;
173167 this . controls . rotateSpeed = 2 ;
@@ -184,68 +178,42 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
184178 this . scene . environment = pmremGenerator . fromScene ( environment ) . texture ;
185179 environment . dispose ( ) ;
186180 TD . load ( this . modeltype , model , source ) ;
187-
188181 } ;
189182
190183 TD . stageContent = function ( object ) {
191- // Ensure all transform matrices are up to date.
192184 object . updateMatrixWorld ( ) ;
193185
194- // Compute axis-aligned bounding box (AABB) and center (x, y, z) in
195- // world space. Size, defined here as a cheap approximation of
196- // model's maximum span in any direction, is computed from the AABB.
197186 const box = new THREE . Box3 ( ) . setFromObject ( object ) ;
198187 const center = box . getCenter ( new THREE . Vector3 ( ) ) ;
199188 const size = box . getSize ( new THREE . Vector3 ( ) ) . length ( ) ;
200189
201- // Center content at the origin, (0, 0, 0).
202190 object . position . x -= center . x ;
203191 object . position . y -= center . y ;
204192 object . position . z -= center . z ;
205193
206- // In glTF, +Y=Up is required. In STL it's unclear, but for backward-
207- // compatibility we keep +Z=Up. Because some three.js features assume
208- // +Y=Up, apply a +Z to +Y conversion for STL.
209194 if ( this . modeltype === 'stl' ) {
210195 const parent = new THREE . Object3D ( ) ;
211196 parent . rotation . set ( - Math . PI / 2 , 0 , 0 ) ;
212197 parent . add ( object ) ;
213198 object = parent ;
214199 }
215200
216- // Prevent controls from dollying out farther than 10x size.
217201 this . controls . maxDistance = size * 10 ;
218202
219- // Constrain camera near and far planes to factors of size. Planes
220- // should fit the content tightly enough that depth buffer
221- // precision is utilized well, but not so tight that the model
222- // clips the near/far planes easily while interacting with controls.
223203 this . camera . near = size / 100 ;
224204 this . camera . far = size * 100 ;
225205 this . camera . updateProjectionMatrix ( ) ;
226206
227- // Default viewing angle is arbitrary and subjective, some models
228- // may benefit from a more top-down or front-facing perspective. To
229- // split the difference somewhat, we use a diagonal. Comparisons:
230- // sketchfab.com: ( 0, -distance, 0 )
231- // viewstl.com: ( 0, 0 distance )
232- // openjscad.org: ( 0, -distance, distance )
233- // thingiverse.com: ( -distance, -distance, distance )
234207 this . camera . position . x += size * 0.75 ;
235208 this . camera . position . y += size * 0.5 ;
236209 this . camera . position . z += size * 0.75 ;
237210
238- // Rotate the camera to look at the object's center, (0, 0, 0).
239211 this . camera . lookAt ( object . position ) ;
240212
241- // Add content to scene.
242213 this . scene . add ( object ) ;
243214 } ;
244215
245-
246- // STL Material wird Geometry hinzugefügt
247216 TD . geometryToObject = function ( geometry ) {
248-
249217 const vertexColors = geometry . hasAttribute ( 'color' ) ;
250218 const material = new THREE . MeshStandardMaterial (
251219 { color : 0xf0ebe8 , flatShading : true , side : THREE . DoubleSide , vertexColors }
@@ -254,17 +222,45 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
254222 } ;
255223
256224 TD . glb = function ( data ) {
257- return data
225+ // animation setup
226+ if ( data . animations && data . animations . length > 0 ) {
227+ console . log ( 'Animationen gefunden:' , data . animations . length ) ;
228+
229+ // removbe old mixer if exists
230+ if ( mixer ) {
231+ mixer . stopAllAction ( ) ;
232+ mixer = null ;
233+ }
234+
235+ mixer = new THREE . AnimationMixer ( data . scene ) ;
236+
237+ data . animations . forEach ( ( clip ) => {
238+ console . log ( 'Animation wird hinzugefügt:' , clip . name ) ;
239+ const action = mixer . clipAction ( clip ) ;
240+ action . play ( ) ;
241+ } ) ;
242+ } else {
243+ console . log ( 'Keine Animationen in dieser GLB-Datei gefunden' ) ;
244+ }
245+
246+ return data ;
258247 }
259248
260-
261249 TD . render = function ( ) {
262250 this . renderer . render ( this . scene , this . camera ) ;
263251 } ;
264252
253+ // animate funktion
265254 TD . animate = function ( ) {
266255 requestAnimationFrame ( this . animate . bind ( this ) ) ;
256+
257+ if ( mixer ) {
258+ const delta = clock . getDelta ( ) ;
259+ mixer . update ( delta ) ;
260+ }
261+
267262 this . controls . update ( ) ;
263+ this . render ( ) ;
268264 } ;
269265
270266 TD . onWindowResize = function ( ) {
@@ -280,33 +276,22 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
280276 this . render ( this . renderer , this . scene , this . camera ) ;
281277 } ;
282278
283- // MMV stuff
284279 TD . unload = function ( ) {
285- // 3D files are wrapped inside a new parent class, where the '3D' badge
286- // is also attached to
287- // we don't want to keep that wrapper class around (could cause unexpected
288- // results), and definitely want that '3D' badge gone...
289280 const $threedParent = this . $container . parent ( '.mw-3d-wrapper' ) ;
290281 $threedParent . replaceWith ( this . $container ) ;
291282 } ;
292283
293284 TD . load = function ( extension , url , source ) {
294- // Abort any loading that might still be happening
295285 if ( this . promise ) {
296286 this . promise . reject ( ) ;
297287 }
298288 this . promise = this . loadFile ( extension , url , source ) ;
299- //this.progressBar.jumpTo(0);
300- // this.progressBar.animateTo(5);
289+
301290 this . promise . then ( ( object ) => {
302291 delete this . promise ;
303292
304- // this.progressBar.hide();
305-
306293 const content = this . modeltype === 'glb' ? object . scene : object ;
307294
308- // STL contains a single mesh, GLB may contain more. Traverse
309- // to handle both cases.
310295 content . traverse ( function ( node ) {
311296 if ( node . isMesh ) {
312297 node . castShadow = true ;
@@ -318,33 +303,30 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
318303
319304 container . appendChild ( this . renderer . domElement ) ;
320305 TD . animate ( ) ;
321-
322- // mw.threed.base.wrap(this.$container);
323306 } ) . progress ( ( progress ) => {
324- // this.progressBar.animateTo(progress);
325- } ) . fail ( ( /* error */ ) => {
326- // this.progressBar.hide();
307+ // Progress handling
308+ } ) . fail ( ( ) => {
327309 delete this . promise ;
328310 } ) ;
329311 } ;
330312
331313 TD . loadFile = function ( extension , url , source ) {
332314 const deferred = $ . Deferred ( ) ;
333315 let loader ;
316+
334317 if ( extension === 'stl' ) {
335318 if ( source === 'server' ) {
336319 loader = new THREE . STLLoader ( this . manager ) . setPath ( 'models/' ) ;
337320 } else {
338321 loader = new THREE . STLLoader ( this . manager ) ;
339322 }
340323 }
324+
341325 if ( extension === 'glb' ) {
342-
343326 const ktx2Loader = new THREE . KTX2Loader ( )
344327 . setTranscoderPath ( 'lib/three/' )
345328 . detectSupport ( this . renderer ) ;
346329
347-
348330 if ( source === 'server' ) {
349331 loader = new THREE . GLTFLoader ( this . manager ) . setPath ( 'models/' ) ;
350332 } else {
@@ -353,13 +335,11 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
353335
354336 loader . setKTX2Loader ( ktx2Loader ) ;
355337 loader . setMeshoptDecoder ( THREE . MeshoptDecoder ) ;
356-
357338 }
358339
359340 const request = loader . load ( url , ( data ) => {
360341 let object = data ;
361342
362-
363343 if ( extension === 'stl' ) {
364344 object = this . geometryToObject ( data ) ;
365345 }
@@ -393,47 +373,19 @@ <h1>Prototype Viewer MediaWiki 3D</h1>
393373
394374 TD . getDimensions = function ( ) {
395375 const width = $ ( window ) . width ( ) ,
396- // height = this.viewer.ui.canvas.$imageWrapper.height();
397376 height = $ ( window ) . height ( ) ;
398377 return { width : width , height : height , ratio : width / height } ;
399378 } ;
400379
401- // MMV stuff
402- // unload when switching images or cleaning up MMV altogether
403- /*
404- $(document).on('mmv-hash mmv-cleanup-overlay', () => {
405- if (singleton) {
406- singleton.unload();
407- }
408- });
409- */
410- /*
411-
412- if (!singleton) {
413- singleton = new ThreeD(viewer);
414- }
415- */
416-
417-
418- /*
419- singleton.init();
420- singleton.animate();
421- singleton.load('stl', e.imageInfo.url);
422- */
423-
424-
425-
380+ // Initialisierung
426381 if ( modeltype === 'glb' ) {
427382 TD . init ( 'ganesha.glb' , 'server' ) ;
428383 }
429384 if ( modeltype === 'stl' ) {
430385 TD . init ( '3D_Model_Hydria.stl' , 'server' ) ;
431386 }
432387
433-
434- // mw.mmv.ThreeD = ThreeD;
435-
436388 </ script >
437389</ body >
438390
439- </ html >
391+ </ html >
0 commit comments