当前位置:网站首页>Threejs loads the city obj model, loads the character gltf model, and tweetjs realizes the movement of characters according to the planned route
Threejs loads the city obj model, loads the character gltf model, and tweetjs realizes the movement of characters according to the planned route
2022-07-05 04:00:00 【Zuo Ben】
1, Introduce :
This example uses r95 edition Three.js library . In the last case ( The front page of the article can be found ) Add a city model (obj Format ), Add persona (gltf Format ), Initialize the movement route , It's used here Tween.js Implemented animation , The character model moves according to the route . Add axis . The renderings are as follows :
2, Main description
Three.js Load model file , And import geometry from it .Three.js Supported model file formats :json、obj/mtl、dae、ply、gltf、glb、svg、pbd..., All the extensions mentioned here , There are many kinds that are not listed here . If you want to load bim Model such as :ifc and rvt Format , It needs to be converted into Three Supported formats , have access to blender Software conversion , Specific course Baidu .
Add city model obj/mtl Format ,obj/mtl It is a combination of two formats , Often used together .obj File definition geometry , and mtl The file defines the material used .obj and mtl They are all text-based formats . The code is as follows :
// Add model
function initModel() {
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath("assets/models/obj_mtl/")
mtlLoader.load('city.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.load('assets/models/obj_mtl/city.obj', function(object) {
mesh = object;
mesh.scale.set(3, 3, 3);
mesh.position.set(18, 0, 18);
scene.add(mesh);
});
});
}
Add persona gltf Format , This format is dedicated to storage 3D Scenarios and models , Its advantage is that it can minimize the file size , And the model can be loaded efficiently . The code is as follows :
// Add persona
function initPeople() {
var loader = new THREE.GLTFLoader();
loader.load('assets/models/CesiumMan/CesiumMan.gltf', function(result) {
result.scene.scale.set(1, 1, 1);
result.scene.translateY(0);
aaa = result.scene;
scene.add(result.scene);
tweenComplete();
mixer = new THREE.AnimationMixer(result.scene);
animationClip = result.animations[0];
clipAction = mixer.clipAction(animationClip).play();
animationClip = clipAction.getClip();
});
}
Use Tween.js The animation effect , adopt Tween.js It is easy to realize the transition between two values of a certain attribute , And all intermediate values between the start value and the end value will be automatically calculated , This process is called tweening( Mend the space ).
function tweenComplete() {
if (i < points.length) {
switch (i) {
case 0:
pobj.rotateY(Math.PI);
break;
case 1:
case 5:
case 8:
case 9:
pobj.rotateY(-0.5 * Math.PI);
break;
case 2:
case 3:
case 4:
case 6:
case 7:
pobj.rotateY(0.5 * Math.PI);
break;
case 10:
mixer.stopAllAction();
break;
}
tween = new TWEEN.Tween(points[i])
.to(points[i + 1], 3000)
.easing(TWEEN.Easing.Linear.None)
.onUpdate(function() {
pobj.position.set(this.x, this.y, this.z);
})
.onComplete(tweenComplete)
.start();
i++;
}
}
3, Source code is as follows :
<!DOCTYPE html>
<html>
<head>
<title>Threejs Load city obj Model , Load characters gltf Model , The character moves according to the planned route </title>
<script type="text/javascript" src="libs/three.js"></script>
<script type="text/javascript" src="libs/OrbitControls.js"></script>
<script type="text/javascript" charset="UTF-8" src="libs/other/Tween.min.js"></script>
<script type="text/javascript" charset="UTF-8" src="libs/three/loaders/GLTFLoader.js"></script>
<script type="text/javascript" src="libs/OBJLoader.js"></script>
<script type="text/javascript" src="libs/MTLLoader.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="dom"></div>
<script type="text/javascript">
var camera;
var renderer;
var clock = new THREE.Clock();
var mixer = new THREE.AnimationMixer();
var clipAction
var animationClip
var pobj
function init() {
// Create a scene , It will contain all our elements , Like an object , Cameras and lights .
var scene = new THREE.Scene();
var urls = [
'assets/textures/cubemap/flowers/posx.jpg',
'assets/textures/cubemap/flowers/negx.jpg',
'assets/textures/cubemap/flowers/posy.jpg',
'assets/textures/cubemap/flowers/negy.jpg',
'assets/textures/cubemap/flowers/posz.jpg',
'assets/textures/cubemap/flowers/negz.jpg'
];
var cubeLoader = new THREE.CubeTextureLoader();
scene.background = cubeLoader.load(urls);
// Create a camera , It defines where we are looking
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
// Aim the camera at the center of the scene
camera.position.x = 20;
camera.position.y = 15;
camera.position.z = 35;
camera.lookAt(scene.position);
var orbit = new THREE.OrbitControls(camera);
// Create a renderer and set the size ,WebGLRenderer The computer graphics card will be used to render the scene
// initialize basic renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
// Add planes to the scene
var plane = createPlaneGeometryBasicMaterial();
scene.add(plane);
// Display the coordinate axis on the screen
var axes = new THREE.AxesHelper(100);
scene.add(axes);
// var trackballControls = initTrackballControls(camera, renderer);
// Add ambient light
scene.add(new THREE.AmbientLight(0x666666));
scene.add(new THREE.AmbientLight("#ffffff", 1));
// Add the output of the renderer to HTML Elements
document.getElementById("dom").appendChild(renderer.domElement);
var points = initLine();
// Add a sphere to the scene
initModel();
initPeople();
// Start animation
renderScene();
var i = 0;
function tweenComplete() {
if (i < points.length) {
switch (i) {
case 0:
pobj.rotateY(Math.PI);
break;
case 1:
case 5:
case 8:
case 9:
pobj.rotateY(-0.5 * Math.PI);
break;
case 2:
case 3:
case 4:
case 6:
case 7:
pobj.rotateY(0.5 * Math.PI);
break;
case 10:
mixer.stopAllAction();
break;
}
tween = new TWEEN.Tween(points[i])
.to(points[i + 1], 3000)
.easing(TWEEN.Easing.Linear.None)
.onUpdate(function() {
pobj.position.set(this.x, this.y, this.z);
})
.onComplete(tweenComplete)
.start();
i++;
}
}
// Add model
function initModel() {
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath("assets/models/obj_mtl/")
mtlLoader.load('city.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.load('assets/models/obj_mtl/city.obj', function(object) {
mesh = object;
mesh.scale.set(3, 3, 3);
mesh.position.y = -5;
scene.add(mesh);
});
});
}
// Add persona
function initPeople() {
var loader = new THREE.GLTFLoader();
loader.load('assets/models/CesiumMan/CesiumMan.gltf', function(result) {
result.scene.scale.set(1, 1, 1);
result.scene.translateY(0);
pobj = result.scene;
scene.add(result.scene);
tweenComplete();
mixer = new THREE.AnimationMixer(result.scene);
animationClip = result.animations[0];
clipAction = mixer.clipAction(animationClip).play();
animationClip = clipAction.getClip();
});
}
// Create a plane
function createPlaneGeometryBasicMaterial() {
var textureLoader = new THREE.TextureLoader();
var cubeMaterial = new THREE.MeshStandardMaterial({
map: textureLoader.load("assets/textures/stone/cd.jpg"),
});
cubeMaterial.map.wrapS = THREE.RepeatWrapping;
cubeMaterial.map.wrapT = THREE.RepeatWrapping;
cubeMaterial.map.repeat.set(18, 18)
// Create the ground plane and set the size
var planeGeometry = new THREE.PlaneGeometry(500, 500);
var plane = new THREE.Mesh(planeGeometry, cubeMaterial);
// Set the plane position and rotate
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = -5;
plane.position.z = 0;
return plane;
}
// Initialize the line
function initLine() {
var pArr = [{
x: 5 * 3,
y: -3.8,
z: -0.7 * 3
}, {
x: -0.6 * 3,
y: -3.8,
z: -0.7 * 3
}, {
x: -0.6 * 3,
y: -3.8,
z: -1.8 * 3
}, {
x: -4 * 3,
y: -3.8,
z: -1.8 * 3
}, {
x: -4 * 3,
y: -3.8,
z: 2.8 * 3
}, {
x: -1.2 * 3,
y: -3.8,
z: 2.8 * 3
}, {
x: -1.2 * 3,
y: -3.8,
z: 4.3 * 3
}, {
x: 1.7 * 3,
y: -3.8,
z: 4.3 * 3
}, {
x: 1.7 * 3,
y: -3.8,
z: -0.4 * 3
}, {
x: 4.4 * 3,
y: -3.8,
z: -0.4 * 3
}, {
x: 4.4 * 3,
y: -3.8,
z: 5 * 3
}];
var points = [];
var geometry = new THREE.Geometry();
for (var i = 0; i < pArr.length; i++) {
var randomX = pArr[i].x;
var randomY = pArr[i].y;
var randomZ = pArr[i].z;
var vector = new THREE.Vector3(randomX, randomY, randomZ);
geometry.vertices.push(vector);
points.push(vector);
}
var material = new THREE.LineBasicMaterial({
color: 0xff0000
});
var line = new THREE.Line(geometry, material);
scene.add(line);
return points;
}
// Animation rendering
var step = 5;
function renderScene() {
TWEEN.update();
orbit.update();
var delta = clock.getDelta();
mixer.update(delta);
// Use requestAnimationFrame Function to render
requestAnimationFrame(renderScene);
renderer.render(scene, camera);
}
// Rendered scenes
renderer.render(scene, camera);
document.addEventListener('mousedown', onDocumentMouseDown, false);
function onDocumentMouseDown(event) {
// Click on the screen to create a vector
var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window
.innerHeight) * 2 + 1, 0.5);
vector = vector.unproject(camera); // Convert the coordinates of the screen into coordinates in the 3D scene
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(mesh.children, true);
console.log(intersects)
if (intersects.length > 0) {
// intersects[0].object.material.color.set("#ffffff");
}
}
// Create a spherical geometry
function createSphereGeometryLambertMaterial(point) {
// Create a sphere
var sphereGeometry = new THREE.SphereGeometry(0.2, 20, 20);
var sphereMaterial = new THREE.MeshBasicMaterial({
color: 0x7777ff,
wireframe: true
});
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0xff0000
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
// Set the object to cast shadows
sphere.castShadow = true;
// Location range
sphere.position.x = point.x;
sphere.position.y = point.y;
sphere.position.z = point.z;
return sphere;
}
}
window.onload = init;
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// Listen for resizing events
window.addEventListener('resize', onResize, false);
</script>
</body>
</html>
If you need a complete code, please leave a message or contact me on wechat :1171053128
边栏推荐
- grandMA2 onPC 3.1.2.5的DMX参数摸索
- Is there a sudden failure on the line? How to make emergency diagnosis, troubleshooting and recovery
- [brush questions] BFS topic selection
- Special Edition: spreadjs v15.1 vs spreadjs v15.0
- Containerization Foundation
- 如何实现实时音视频聊天功能
- UI自動化測試從此告別手動下載瀏覽器驅動
- [C language] address book - dynamic and static implementation
- “金九银十”是找工作的最佳时期吗?那倒未必
- What is test development? Why do so many companies hire test developers now?
猜你喜欢
error Couldn‘t find a package.json file in “你的路径“
已解决(sqlalchemy+pandas.read_sql)AttributeError: ‘Engine‘ object has no attribute ‘execution_options‘
Deep learning - LSTM Foundation
laravel8 导出Excle文件
[software reverse analysis tool] disassembly and decompilation tool
【web審計-源碼泄露】獲取源碼方法,利用工具
Clickhouse synchronization MySQL (based on materialization engine)
JVM garbage collection
UI自動化測試從此告別手動下載瀏覽器驅動
UE4 DMX和grandMA2 onPC 3.1.2.5的操作流程
随机推荐
优先使用对象组合,而不是类继承
MindFusion.Virtual Keyboard for WPF
Assembly - getting started
MindFusion. Virtual Keyboard for WPF
Operation flow of UE4 DMX and grandma2 onpc 3.1.2.5
lds链接的 顺序问题
Google Chrome CSS will not update unless the cache is cleared - Google Chrome CSS doesn't update unless clear cache
C language course setting: cinema ticket selling management system
【web審計-源碼泄露】獲取源碼方法,利用工具
English essential vocabulary 3400
[untitled]
一文带你了解BI的前世今身与企业数字化转型的关系
It took two nights to get Wu Enda's machine learning course certificate from Stanford University
Differences among 10 addressing modes
请问一下我的请求是条件更新,但在buffer中就被拦截了,这种情况我只能每次去flush缓存么?
[web Audit - source code disclosure] obtain source code methods and use tools
[software reverse analysis tool] disassembly and decompilation tool
ABP vNext microservice architecture detailed tutorial - distributed permission framework (Part 1)
EasyCVR平台出现WebRTC协议视频播放不了是什么原因?
深度学习——LSTM基础