game objects module

This commit is contained in:
2024-11-05 19:42:33 +02:00
parent 2978f11869
commit e3a2a0251d
4 changed files with 93 additions and 26 deletions
+3
View File
@@ -4,6 +4,9 @@ node_modules
/out /out
/repo /repo
#temporary:
/public/static
# local env files # local env files
.env.local .env.local
.env.*.local .env.*.local
+3
View File
@@ -1,5 +1,7 @@
import decompress from "decompress"; import decompress from "decompress";
import sharp from 'sharp'; import sharp from 'sharp';
sharp.cache({ files : 0 });
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
@@ -111,6 +113,7 @@ class GameObjectsManager{
let result = await decompress(src, def); let result = await decompress(src, def);
object.asset.list = result.map(f=>f.path); object.asset.list = result.map(f=>f.path);
object.asset.type = 'bundle'; object.asset.type = 'bundle';
object.asset.name = `${object.id}/` + result.find(f=>f.path.endsWith('.gltf'))?.path;
}else{ }else{
object.asset.type = 'single'; object.asset.type = 'single';
await fs.promises.copyFile(src, def + ext); await fs.promises.copyFile(src, def + ext);
+56 -15
View File
@@ -1,33 +1,74 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/Addons.js';
import { OrbitControls } from 'three/examples/jsm/Addons.js';
import { MapControls } from 'three/addons/controls/MapControls.js';
import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
import { TransformControls } from 'three/addons/controls/TransformControls.js';
class GameEngine { class GameEngine {
constructor() { constructor(domNode) {
const width = window.innerWidth/2, height = window.innerHeight/2; const width = 1200, height = 800;
const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10); const camera = new THREE.PerspectiveCamera(70, width / height, 0.1, 10000);
camera.position.z = 1; //camera.position.set(-10, -10, 50);
const scene = new THREE.Scene(); const scene = new THREE.Scene();
// this.light = new THREE.AmbientLight( 0x404040, 0 ); // soft white light
const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2); // scene.add( this.light );
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
function animate(time) { function animate(time) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render(scene, camera); renderer.render(scene, camera);
controls.update();
} }
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
preserveDrawingBuffer: true
});
renderer.setPixelRatio( window.devicePixelRatio );
const controls = new OrbitControls( camera, renderer.domElement );
//const controls = new MapControls( camera, renderer.domElement );
this.transformControls = new TransformControls( camera, renderer.domElement );
this.transformControls.addEventListener( 'dragging-changed', function ( event ) {
controls.enabled = ! event.value;
} );
// controls.enableDamping = true;
// controls.screenSpacePanning = true;
renderer.setSize(width, height); renderer.setSize(width, height);
renderer.setAnimationLoop(animate); renderer.setAnimationLoop(animate);
this.renderer = renderer; this.renderer = renderer;
this.scene = scene;
this.loader = new GLTFLoader();
this.camera = camera;
this.controls = controls;
domNode.appendChild(renderer.domElement);
new THREE.TextureLoader().load('/static/textures/bck-preview.jpg', texture=>{
texture.encoding = THREE.sRGBEncoding;
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = new THREE.Color(0.7,0.8,1);
scene.environment = texture;
})
}
$ = THREE;
async load(url, progress){
return new Promise((resolve, reject)=>{
this.loader.load(url, resolve, progress, reject)
})
}
async captureScreenshot(type = 'image/webp', quality = 80){
return new Promise((resolve, reject)=>{
this.renderer.domElement.toBlob(resolve, type, quality)
})
}
stop(){
this.renderer.setAnimationLoop(null);
} }
} }
+31 -11
View File
@@ -17,16 +17,15 @@
</v-card-actions> </v-card-actions>
</v-card> </v-card>
<v-card :title="$l.preview" class="container my-3" v-if="object.asset"> <v-card :title="$l.preview" class="container my-3" v-show="object.asset">
<div ref="target" v-if="object?.asset?.type == 'bundle'"></div> <div ref="target" v-show="object?.asset?.type == 'bundle'"></div>
<v-img v-else :src="`/asset/default/${object.asset?.name}`"></v-img> <v-img v-show="object?.asset?.type == 'single'" :src="`/asset/default/${object.asset?.name}`"></v-img>
</v-card> </v-card>
</template> </template>
<script> <script>
import { GameEngine } from '@/gameEngine'; import { GameEngine } from '@/gameEngine';
let gameEngine = null;
const gameEngine = new GameEngine();
export default { export default {
data() { data() {
@@ -44,13 +43,15 @@ export default {
loading: false loading: false
} }
}, },
async created(){ async mounted() {
if (this.id && this.id != 'add'){ if (this.id && this.id != 'add'){
this.object = (await this.$api.gameObject.load(this.id)).data; this.object = (await this.$api.gameObject.load(this.id)).data;
} }
gameEngine = new GameEngine(this.$refs.target);
await this.loadAsset();
}, },
mounted() { beforeUnmount(){
//this.$refs.target?.appendChild(gameEngine.renderer.domElement); gameEngine?.stop();
}, },
computed: { computed: {
fileToUpload(){ fileToUpload(){
@@ -61,13 +62,14 @@ export default {
} }
}, },
methods: { methods: {
async saveAndPreview() { async saveAndPreview(params) {
this.loading = true; this.loading = true;
try { try {
let fd = new FormData(); let fd = new FormData();
let keys = ['name', 'type']; let keys = ['name', 'type'];
if (this.fileToUpload) keys.push('file'); if (this.fileToUpload) keys.push('file');
if (this.id != 'add') keys.push('id'); if (this.id != 'add') keys.push('id');
if (this.object.thumb) keys.push('thumb');
keys.forEach(e=>fd.append(e, this.object[e])) keys.forEach(e=>fd.append(e, this.object[e]))
let result = await this.$api.gameObject.save(fd); let result = await this.$api.gameObject.save(fd);
@@ -75,13 +77,31 @@ export default {
if (this.id == 'add'){ if (this.id == 'add'){
this.$router.replace({ params: {id: this.object.id} }); this.$router.replace({ params: {id: this.object.id} });
} }
if (!params?.thumbOnly) await this.loadAsset();
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
this.loading = false this.loading = false
}, },
captureThumbnail() { async loadAsset(){
if (this.object.asset?.type == 'bundle'){
let gltf = await gameEngine.load(`/asset/default/${this.object.asset.name}`);
gameEngine.scene.clear();
console.log(gltf)
let bb = new gameEngine.$.Box3().setFromObject(gltf.scene);
gltf.scene.traverse( function( object ) {
object.frustumCulled = false;
} );
gameEngine.camera.position.set(bb.max.x, bb.max.y, bb.max.z);
gameEngine.controls.target.set((bb.max.x + bb.min.x)/2, (bb.max.y+bb.min.y)/2, (bb.max.z + bb.min.z)/2)
gameEngine.controls.update();
gameEngine.scene.add(gltf.scene);
//gameEngine.scene.add(gameEngine.light);
}
},
async captureThumbnail() {
this.object.thumb = await gameEngine.captureScreenshot();
await this.saveAndPreview({thumbOnly: true});
}, },
async publish() { async publish() {