logs in console, caching in getAgentProps, console createAgent independent of GUI

This commit is contained in:
STEINNI
2025-12-06 18:53:23 +00:00
parent 1143c52c11
commit c1d0a16cf3
26 changed files with 18025 additions and 100 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

+11
View File
@@ -0,0 +1,11 @@
Model Information:
* title: Mech Drone
* source: https://sketchfab.com/3d-models/mech-drone-8d06874aac5246c59edb4adbe3606e0e
* author: Willy Decarpentrie (https://sketchfab.com/skudgee)
Model License:
* license type: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
* requirements: Author must be credited. Commercial use is allowed.
If you use this 3D model in your project be sure to copy paste this credit wherever you share it:
This work is based on "Mech Drone" (https://sketchfab.com/3d-models/mech-drone-8d06874aac5246c59edb4adbe3606e0e) by Willy Decarpentrie (https://sketchfab.com/skudgee) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 MiB

+40
View File
@@ -0,0 +1,40 @@
//////////////TESTING /////////////////
this.threeClock = new THREE.Clock()
const loader = new GLTFLoader().setPath( '/app/assets/3dModels/' );
loader.load( 'mechdrone/scene.gltf', async function ( gltf ) {
const model = gltf.scene;
// wait until the model can be added to the scene without blocking due to shader compilation
await this.renderer.compileAsync( model, this.camera, this.scene );
model.scale.set(5,5,5)
this.scene.add( model )
model.traverse(obj => {
console.log(
obj.type,
obj.name || '(no name)',
obj.isBone ? '[BONE]' : ''
)
if (obj.isMesh && obj.material && obj.material.color) {
const c = obj.material.color.clone()
const boost = 0.1 // réglage global
obj.material.emissive = c
obj.material.emissiveIntensity = boost
}
})
this.leftArm = model.getObjectByName('ArmL1_01')
if (gltf.animations && gltf.animations.length > 0) {
this.mixer = new THREE.AnimationMixer(gltf.scene)
// On joue la première animation
const action = this.mixer.clipAction(gltf.animations[0])
action.play()
}
}.bind(this) )
// In Render:
const delta = this.threeClock.getDelta()
if(this.mixer) this.mixer.update(delta)
+29 -4
View File
@@ -1,5 +1,5 @@
<style>
.kf-editor .inner-console .results .api-summary{ border: 1px solid white;margin: .5em;width: 90%; }
.kf-editor .inner-console .results .api-summary{ border: 1px solid white;margin: .5em;width: 90%; border-radius: 7px;}
.kf-editor .inner-console .results .api-summary h1{
font-size: 1.5em;
margin: 0;
@@ -12,6 +12,7 @@
background: #DDD;
color: black;
}
.kf-editor .inner-console .results button[data-trigger="onExample"]{ margin-left: 2em; }
</style>
<div class="title">Javascript Keyframe console</div>
Use any combination of Javascript and API calls to update your keyframe scene.<br>
@@ -21,8 +22,32 @@ Special commands:<br>
<div class="api-summary">
<h1>API:</h1>
<ul>
<li>Create an agent: <b>newAgent(type, properties)</b> - returns the AID</li>
<li>Remove an agent: <b>removeAgent(aid)</b></li>
<li>Update an agent: <b>updateAgent(aid, properties)</b></li>
<li>Log here: <b>log()</b> - any number of arguments of any type</li>
<li>Create an agent: <b>createAgent(type, properties)</b> - Promise returning the AID <button eicbutton info xxsmall data-trigger="onSnippet" data-snippet="createAgent">Snippet</button></li>
<li>Remove an agent: <b>removeAgent(aid)</b> <button eicbutton info xxsmall data-trigger="onSnippet" data-snippet="removeAgent">Snippet</button></li>
<li>Update an agent: <b>updateAgent(aid, properties)</b> <button eicbutton info xxsmall data-trigger="onSnippet" data-snippet="updateAgent">Snippet</button></li>
<li>List agent types: <b>listAgentTypes()</b> <button eicbutton info xxsmall data-trigger="onSnippet" data-snippet="listAgentTypes">Snippet</button></li>
<li>List agents on scene: <b>listAgentsOnScene()</b> <button eicbutton info xxsmall data-trigger="onSnippet" data-snippet="listAgentsOnScene">Snippet</button></li>
</ul>
</div>
<div class="snippet" data-snippet="createAgent" style="display:none">
const agtIds = []
for(let i=0; i<360; i+=22.5){
agtIds.push(
await createAgent(1, { position: { x: 10*Math.sin(i*Math.PI/180), y: 10*Math.cos(i*Math.PI/180), z: 0 } } )
)
}
log(agtIds)
</div>
<div class="snippet" data-snippet="removeAgent" style="display:none">
</div>
<div class="snippet" data-snippet="updateAgent" style="display:none">
</div>
<div class="snippet" data-snippet="listAgentTypes" style="display:none">
for(const agt of listAgentTypes() console.log(agt)
</div>
<div class="snippet" data-snippet="listAgentsOnScene" style="display:none">
for(const agt of listAgentsOnScene() console.log(agt)
</div>
Binary file not shown.
+240
View File
@@ -0,0 +1,240 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - FBX loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="https://threejs.org/examples/main.css">
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
"three/examples/jsm/loaders/FontLoader.js": "https://unpkg.com/three@0.160.0/examples/jsm/loaders/FontLoader.js",
"three/examples/jsm/geometries/TextGeometry.js": "https://unpkg.com/three@0.160.0/examples/jsm/geometries/TextGeometry.js",
"three/examples/jsm/loaders/RGBELoader.js": "https://unpkg.com/three@0.160.0/examples/jsm/loaders/RGBELoader.js",
"three/examples/jsm/controls/OrbitControls.js": "https://unpkg.com/three@0.160.0/examples/jsm/controls/OrbitControls.js",
"three/examples/jsm/libs/tween.module.js": "https://unpkg.com/three@0.160.0/examples/jsm/libs/tween.module.js",
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/"
}
}
</script>
</head>
<body>
<div id="info">
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - FBXLoader<br />
Character and animation from <a href="https://www.mixamo.com/" target="_blank" rel="noopener">Mixamo</a>
</div>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
const manager = new THREE.LoadingManager();
let camera, scene, renderer, stats, object, loader, guiMorphsFolder;
let mixer;
const clock = new THREE.Clock();
const params = {
asset: 'Samba Dancing'
};
const assets = [
'Samba Dancing',
'morph_test',
'monkey',
'monkey_embedded_texture',
'vCube',
];
init();
function init() {
const container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 100, 200, 300 );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xa0a0a0 );
scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444, 5 );
hemiLight.position.set( 0, 200, 0 );
scene.add( hemiLight );
const dirLight = new THREE.DirectionalLight( 0xffffff, 5 );
dirLight.position.set( 0, 200, 100 );
dirLight.castShadow = true;
dirLight.shadow.camera.top = 180;
dirLight.shadow.camera.bottom = - 100;
dirLight.shadow.camera.left = - 120;
dirLight.shadow.camera.right = 120;
scene.add( dirLight );
// scene.add( new THREE.CameraHelper( dirLight.shadow.camera ) );
// ground
const mesh = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
mesh.rotation.x = - Math.PI / 2;
mesh.receiveShadow = true;
scene.add( mesh );
const grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
grid.material.opacity = 0.2;
grid.material.transparent = true;
scene.add( grid );
loader = new FBXLoader( manager );
loadAsset( params.asset );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animate );
renderer.shadowMap.enabled = true;
container.appendChild( renderer.domElement );
const controls = new OrbitControls( camera, renderer.domElement );
controls.target.set( 0, 100, 0 );
controls.update();
window.addEventListener( 'resize', onWindowResize );
// stats
stats = new Stats();
container.appendChild( stats.dom );
const gui = new GUI();
gui.add( params, 'asset', assets ).onChange( function ( value ) {
loadAsset( value );
} );
guiMorphsFolder = gui.addFolder( 'Morphs' ).hide();
}
function loadAsset( asset ) {
loader.load( 'models/ffbxbx/' + asset + '.fbx', function ( group ) {
if ( object ) {
object.traverse( function ( child ) {
if ( child.isSkinnedMesh ) {
child.skeleton.dispose();
}
if ( child.material ) {
const materials = Array.isArray( child.material ) ? child.material : [ child.material ];
materials.forEach( material => {
if ( material.map ) material.map.dispose();
material.dispose();
} );
}
if ( child.geometry ) child.geometry.dispose();
} );
scene.remove( object );
}
//
object = group;
if ( object.animations && object.animations.length ) {
mixer = new THREE.AnimationMixer( object );
const action = mixer.clipAction( object.animations[ 0 ] );
action.play();
} else {
mixer = null;
}
guiMorphsFolder.children.forEach( ( child ) => child.destroy() );
guiMorphsFolder.hide();
object.traverse( function ( child ) {
if ( child.isMesh ) {
child.castShadow = true;
child.receiveShadow = true;
if ( child.morphTargetDictionary ) {
guiMorphsFolder.show();
const meshFolder = guiMorphsFolder.addFolder( child.name || child.uuid );
Object.keys( child.morphTargetDictionary ).forEach( ( key ) => {
meshFolder.add( child.morphTargetInfluences, child.morphTargetDictionary[ key ], 0, 1, 0.01 );
} );
}
}
} );
scene.add( object );
} );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
const delta = clock.getDelta();
if ( mixer ) mixer.update( delta );
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>