当前位置:网站首页>Three. JS introduction learning notes 12: the model moves along any trajectory line
Three. JS introduction learning notes 12: the model moves along any trajectory line
2022-07-07 15:49:00 【Jiang Duoduo_ Mostly Harmless 】
Reference learning
http://www.yanhuangxueyuan.com/doc/Three.js/curveRun.html
http://www.yanhuangxueyuan.com/doc/three.js/ringrun.html
An example : Cube trajectory motion
// Create a model , Used to move along a three-dimensional curve
var box = new THREE.BoxGeometry(5, 5, 5);
var material = new THREE.MeshLambertMaterial({
color: 0x0000ff
}); // Material object
var mesh = new THREE.Mesh(box, material);
scene.add(mesh);
mesh.position.set(-10, -50, -50)
// By class CatmullRomCurve3 Create a 3D Splines
var curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-10, -50, -50),
new THREE.Vector3(10, 0, 0),
new THREE.Vector3(8, 50, 50),
new THREE.Vector3(-5, 0, 100)
]);
// The spline curve is evenly divided 100 branch , return 51 Vertex coordinates
var points = curve.getPoints(100);
console.log('points', points);// View the returned vertex coordinates on the console
var geometry = new THREE.Geometry();
// Assign coordinates to the vertices of the curve from the geometry
geometry.vertices = points
var material = new THREE.LineBasicMaterial({
color: 0x4488ff
});
var line = new THREE.Line(geometry, material);
scene.add(line)
// adopt Threejs Frame animation related API Play the mesh model and animate along the curve
// Declare an array to store time series
let arr = []
for (let i = 0; i < 101; i++) {
arr.push(i)
}
// Generate a time series
var times = new Float32Array(arr);
var posArr = []
points.forEach(elem => {
posArr.push(elem.x, elem.y, elem.z)
});
// Create a position coordinate series corresponding to the time series
var values = new Float32Array(posArr);
// Create keyframe data for a frame animation , The position sequence on the curve corresponds to a time series
var posTrack = new THREE.KeyframeTrack('.position', times, values);
let duration = 101;
let clip = new THREE.AnimationClip("default", duration, [posTrack]);
var mixer = new THREE.AnimationMixer(mesh);
let AnimationAction = mixer.clipAction(clip);
AnimationAction.timeScale = 20;
AnimationAction.play();
var clock = new THREE.Clock();// Declare a clock object
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
// Update the time of frame animation
mixer.update(clock.getDelta());
}
render();
A complete example
<!DOCTYPE html>
<html lang="en">
<head>
<title>3D</title>
<meta charset="utf-8">
<!-- The adaptive -->
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script type="text/javascript" src="js/OrbitControls.js"></script>
<script>
var stats, light;
var camera, scene, raycaster, renderer;
var mouse = new THREE.Vector2(), INTERSECTED;// Intersecting
var radius = 100, theta = 0;
init();
function init() {
// init scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf0f0f0 );
// init camera
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set(15,15,15);
// camera.lookAt(new THREE.Vector3(0,0,0));
camera.lookAt( scene.position );
scene.add(camera);
//light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 1, 1, 1 ).normalize();// Vector attribute vector is converted to unit vector , Set the direction to be the same as the original vector , The length is 1
light.intensity=1.5;// Strength
scene.add( light );
// object
// Add the group to the scene
// base
var loader = new THREE.ObjectLoader();
loader.load("json/untitled5.json", function(objectBottom) {
objectBottom.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
objectBottom.scale.multiplyScalar(350);//3 Multiple size
// var mesh1 = objectBottom;
objectBottom.position.set(0,0,0);
objectBottom.rotation.x = -Math.PI;// rotate 180 degree
scene.add(objectBottom);
});
var loaderCar = new THREE.ObjectLoader();
loaderCar.load("json/che0312.json", function(object2) {
object2.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
object2.scale.multiplyScalar(55);
// var mesh2 = object2;
object2.position.set(4.8,1.3,-3);
// object2.rotation.x = -Math.PI;// rotate 180 degree
scene.add(object2);
});
// Machine tool 5000 Add materials to web pages
var loaderTool = new THREE.ObjectLoader();
loaderTool.load("json/tool_new.json", function(object3) {
object3.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshLambertMaterial({
color: 0xffffff,
side: THREE.DoubleSide
});
}
});
object3.scale.multiplyScalar(60);//3 Multiple size
// var mesh3 = object3;
object3.position.set(1,3,-2);
object3.rotation.z = -Math.PI;// rotate 180 degree
object3.rotation.y = -Math.PI;// rotate 180 degree
scene.add(object3);
});
// Machine tool 8000
var loaderTool2 = new THREE.ObjectLoader();
loaderTool2.load("json/tool_new.json", function(object4) {
object4.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshLambertMaterial({
color: 0xffffff,
side: THREE.DoubleSide
});
}
});
object4.scale.multiplyScalar(75);//3 Multiple size
// mesh = object4;
object4.position.set(0.7,3.3,-6);
object4.rotation.z = -Math.PI;// rotate 180 degree
object4.rotation.y = -Math.PI;// rotate 180 degree
scene.add(object4);
});
// Cache Library
var loaderC1 = new THREE.ObjectLoader();
loaderC1.load("json/cfbx3.json", function(obj1) {
obj1.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj1.scale.multiplyScalar(3);//3 Multiple size
mesh = obj1;
obj1.position.set(0,1.3,8.5)
obj1.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj1);
});
var loaderC2 = new THREE.ObjectLoader();
loaderC2.load("json/cfbx3.json", function(obj2) {
obj2.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj2.scale.multiplyScalar(3);//3 Multiple size
mesh = obj2;
obj2.position.set(0,1.3,6)
obj2.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj2);
});
var loaderC3 = new THREE.ObjectLoader();
loaderC3.load("json/cfbx3.json", function(obj3) {
obj3.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj3.scale.multiplyScalar(3);//3 Multiple size
mesh = obj3;
obj3.position.set(0,1.3,4.5)
obj3.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj3);
});
var loaderC4 = new THREE.ObjectLoader();
loaderC4.load("json/cfbx3.json", function(obj4) {
obj4.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj4.scale.multiplyScalar(3);//3 Multiple size
mesh = obj4;
obj4.position.set(0,1.3,3)
obj4.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj4);
});
var loaderC5 = new THREE.ObjectLoader();
loaderC5.load("json/cfbx3.json", function(obj5) {
obj5.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material.side = THREE.DoubleSide;
}
});
obj5.scale.multiplyScalar(3);//3 Multiple size
mesh = obj5;
obj5.position.set(0,1.3,1.5)
obj5.rotation.z = -Math.PI;// rotate 180 degree
scene.add(obj5);
});
// ray
raycaster = new THREE.Raycaster();
/* var raycaster = new THREE.Raycaster();
var mouseVector = new THREE.Vector3();*/
//renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementsByTagName("body")[0].appendChild(renderer.domElement);
// monitor
document.addEventListener( "mousedown", onDocumentMouseDown, false );
// Window changes
window.addEventListener( "resize", onWindowResize, false );
// plug-in unit
var controls = new THREE.OrbitControls( camera, renderer.domElement );//camera and render The variable of is consistent with the variable set by the camera and renderer
// If you use animate When the method is used , Delete this function
//controls.addEventListener( 'change', render );
// Make the animation rotate or damp when cycling Does the meaning have inertia
controls.enableDamping = true;
// Dynamic damping coefficient It's the mouse drag rotation sensitivity
//controls.dampingFactor = 0.25;
// Can I zoom
controls.enableZoom = true;
// Whether to rotate automatically
controls.autoRotate = true;
// Set the maximum distance from the camera to the origin
controls.minDistance = 1;
// Set the maximum distance from the camera to the origin
controls.maxDistance = 200;
// Whether to turn on right-click drag and drop
controls.enablePan = true;
}//function end
// Window changes
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
// camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
// Coordinate transformation
function onDocumentMouseDown( event ) {
// Mouse event starts
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// Update the ray with camera and mouse position
raycaster.setFromCamera( mouse, camera );
// Calculate the focus of objects and rays
var intersects = raycaster.intersectObjects( scene.children ,true);// Rays pass through objects , Automatically sort from near to far
// The first one is
/* for ( var i = 0; i < intersects.length; i++ ) {
// intersects[ i ].object.material.color.set( 0xff0000 );
intersects[ i ].object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshLambertMaterial({
color: 0xffff00,
side: THREE.DoubleSide
});
}
});
} */
// The second kind
if ( intersects.length > 0 ) {
// When there are objects
if ( INTERSECTED != intersects[ 0 ].object ) {
// The last selection is not equal to the current selection , It's time to replace ,intersects[ 0 ] Is the current selection At the front , It is automatically sorted
if ( INTERSECTED )
if( INTERSECTED.material .length==undefined){
INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );// The last selected material should be replaced with the original material
}
INTERSECTED = intersects[ 0 ].object;
if( INTERSECTED.material .length==undefined){
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();// Save the current materials
INTERSECTED.material.emissive.setHex( 0xff0000 );// Color change
}
}
} else {
// When selecting the blank space
//
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = null;
}
}//mousedown The mouse event ends
// The trajectory
// Create a model , Used to move along a three-dimensional curve
var box = new THREE.BoxGeometry(5, 5, 5);
var material = new THREE.MeshLambertMaterial({
color: 0x0000ff
}); // Material object
var mesh = new THREE.Mesh(box, material);
scene.add(mesh);
mesh.position.set(-10, -50, -50)
// By class CatmullRomCurve3 Create a 3D Splines
var curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-10, -50, -50),
new THREE.Vector3(10, 0, 0),
new THREE.Vector3(8, 50, 50),
new THREE.Vector3(-5, 0, 100)
]);
// The spline curve is evenly divided 100 branch , return 51 Vertex coordinates
var points = curve.getPoints(100);
console.log('points', points);// View the returned vertex coordinates on the console
var geometry = new THREE.Geometry();
// Assign coordinates to the vertices of the curve from the geometry
geometry.vertices = points
var material = new THREE.LineBasicMaterial({
color: 0x4488ff
});
var line = new THREE.Line(geometry, material);
scene.add(line)
// adopt Threejs Frame animation related API Play the mesh model and animate along the curve
// Declare an array to store time series
let arr = []
for (let i = 0; i < 101; i++) {
arr.push(i)
}
// Generate a time series
var times = new Float32Array(arr);
var posArr = []
points.forEach(elem => {
posArr.push(elem.x, elem.y, elem.z)
});
// Create a position coordinate series corresponding to the time series
var values = new Float32Array(posArr);
// Create keyframe data for a frame animation , The position sequence on the curve corresponds to a time series
var posTrack = new THREE.KeyframeTrack('.position', times, values);
let duration = 101;
let clip = new THREE.AnimationClip("default", duration, [posTrack]);
var mixer = new THREE.AnimationMixer(mesh);
let AnimationAction = mixer.clipAction(clip);
AnimationAction.timeScale = 20;
AnimationAction.play();
var clock = new THREE.Clock();// Declare a clock object
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
// Update the time of frame animation
mixer.update(clock.getDelta());
}
//render();
function animate() {
requestAnimationFrame( animate );
render();
}
animate();
</script>
</body>
</html>
CatmullRomCurve3 establish 3D Splines
One . Create a line
Point line surface learning Add link description
1. Create two points
var p1 = new THREE.Vector3( 0, 0, 0);
var p2 = new THREE.Vector3( 1, 2, 0);
2. Put both points in Geometry Medium vertices in
geometry.vertices Is an array , For storage points , Use push Method can put points in , Next, put two points to geometry.vertices in
var geometry = new THREE.Geometry();
geometry.vertices.push(p1);
geometry.vertices.push(p2);
We can also define colors
var color1 = new THREE.Color( 0x444444 ),
color2 = new THREE.Color( 0xFF0000 );
// Set different colors for different vertices
geometry.colors.push( color1, color2 );
geometry in colors Represents the color of the vertex , Must be in the material vertexColors be equal to THREE.VertexColors when , Color works , If vertexColors be equal to THREE.NoColors when , Color has no effect . Then you will get the material color Value , This is very important , You must remember .
3. Tectonic line
var line = new THREE.Line(geometry, material, THREE.LinePieces );
meterial The parameter is material , You can choose basic LineBasicMaterial
The first parameter is geometry geometry, It contains 2 Vertex and vertex color . The second parameter is the material of the line , Or the properties of lines , Indicates how the line is colored . The third parameter is the connection mode of a group of points .
We can use the following code to change the color and transparency of the line , So if you let the object move along the line , Want hidden lines , Just make the line transparent
var material = new THREE.LineBasicMaterial({
color:0x000000, opacity:0.2});
The opacity setting here is not easy to use
Position and rotation of the line
line.position.x = (i * 50) - 500;
line.rotation.y = 90 * Math.PI / 180;
Learning reference
https://blog.csdn.net/qq_36311091/article/details/81016057
LineBasicMaterial( parameters )
Parameters Is an object that defines the appearance of a material , It contains multiple attributes to define the material , These properties are :
Color: The color of the line , use 16 Base to represent , The default color is white .
Linewidth: The width of the line , Default time 1 Unit width .
Linecap: The appearance of both ends of the line , The default is fillet endpoint , The effect can only be seen when the lines are thick , If the lines are very thin , Then you can hardly see the effect .
Linejoin: The appearance at the connection point of two lines , The default is “round”, Represents a fillet .
VertexColors: Defines whether the line material uses vertex colors , This is a boolean value . intend , The color of each part of the line will be interpolated according to the color of the vertex .
Fog: Defines whether the color of the material is affected by the global fog effect .
We use vertex colors here vertexColors: THREE.VertexColors, The color of the line will be calculated according to the vertex .
var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
4. Add lines to the scene
scene.add(line);
** Establish grid coordinate system **
[ Reference Content ](https://blog.csdn.net/soraduo/article/details/97920230?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158468316619724846408253%2522%252C%2522scm%2522%253A%252220140713.130056874..%2522%257D&request_id=158468316619724846408253&biz_id=0&utm_source=distribute.pc_search_result.none-task)
```javascript
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title> Grid </title>
<script src="js/Three.js"></script>
<!-- introduce three.js Support -->
<style type="text/css">
div#canvas-frame{
border: none;
cursor: pointer;
width: 100%;
height: 600px;
background-color: #EEEEEE;
}
</style>
<script>
var renderer;
function initThree() {
/** * obtain canvas-frame Width * @type {HTMLElement} */
width=document.getElementById('canvas-frame').clientWidth;
/** * Get height */
height=document.getElementById('canvas-frame').clientHeight;
/** * Initialize the renderer , Set the parameter to anti aliasing * @type {WebGLRenderer} */
renderer=new THREE.WebGLRenderer({
antialias:true});
/** * Set the size of the rendering */
renderer.setSize(width,height);
/** * Render all child nodes */
document.getElementById('canvas-frame').appendChild(renderer.domElement);
/** * Set transparency */
renderer.setClearColor(0xFFFFFF,1.0);
}
var camera;
/** * Camera settings */
function initCamera() {
camera=new THREE.PerspectiveCamera(45,width/height,1,10000);
camera.position.x=0;
camera.position.y=1000;
camera.position.z=0;
camera.up.x=0;
camera.up.y=0;
camera.up.z=1;
camera.lookAt(
{
x:0,
y:0,
z:0
}
);
}
/** * Setting scene */
var scene;
function initScene() {
scene=new THREE.Scene();
}
/** * Set light */
var light;
function initLight() {
light=new THREE.DirectionalLight(0xFF0000,1.0,0);
light.position.set(100,100,200);
scene.add(light);
}
var cube;
function initObject() {
var geometry=new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-500,0,0));
geometry.vertices.push(new THREE.Vector3(500,0,0));
for(var i=0;i<=20;i++) {
var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({
color: 0x000000, opacity: 0.2}))
line.position.z = (i * 50) - 500;
scene.add(line);
var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({
color: 0x000000, opacity: 0.2}));
line.position.x = (i * 50) - 500;
line.rotation.y = 90 * Math.PI / 180;
scene.add(line);
}
}
function threeStart() {
initThree();
initCamera();
initScene();
initLight();
initObject();
renderer.clear();
renderer.render(scene, camera);
}
</script>
</head>
<body οnlοad="threeStart()">
<div id="canvas-frame">
</div>
</body>
</html>
Two . Draw an arc
/Create a closed wavey loop
var curve = new THREE.CatmullRomCurve3( [
new THREE.Vector3( -10, 0, 10 ),
new THREE.Vector3( -5, 5, 5 ),
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 5, -5, 5 ),
new THREE.Vector3( 10, 0, 10 )
] );
var points = curve.getPoints( 50 );
var geometry = new THREE.BufferGeometry().setFromPoints( points );
var material = new THREE.LineBasicMaterial( {
color : 0xff0000 } );
// Create the final object to add to the scene
var curveObject = new THREE.Line( geometry, material );
THREE.CatmullRomCurve3().getPoints(divisions): This method returns a Vector3 Array , Divide the curve into divisions paragraph , Return the coordinate array of each point . The above example is through getPoint(50) Back on curve
50 The coordinates of the bisector , Then build a curve through these coordinates .
THREE.CatmullRomCurve3().getPoint(t):t yes 0 To 1 Value between , Return a coordinate value
THREE.CatmullRomCurve3().getPointAt(u): In the relative position of the curve , Return the coordinate value according to the arc length
THREE.CatmullRomCurve3().getSpacedPoints(length):
THREE.CatmullRomCurve3().getLength(): Returns the length of the curve
THREE.CatmullRomCurve3().getLengths(divisions): Return the length list of cumulative segments
Let the light source move along the arc
1. Create a new arc
Reference learning
http://www.webgl3d.cn/threejs/docs/#api/zh/extras/core/Curve
Create an arc
// Create curves
var curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-10, 10, 10),
new THREE.Vector3(-5, 5, 5),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(5, -5, 5),
new THREE.Vector3(10, 0, 10)
]);
// Create a light source
var pointLight = new PointLight(0xff0000, 1, 100, 1);
pointLight.name = 'pointLight';
// Get the point above the arc , However, the light source moves along these points .
var pos = 0;
function move(){
light = scene.getObjectByName('pointLight');
if(pos < 1){
light.position = curve.getPointAt(pos);// The relative position of the curve , Return value according to arc length , The scope is 0-1
pos += 0.001
}else{
pos = 0;
}
}
边栏推荐
- XMIND frame drawing tool
- jacoco代码覆盖率
- How to build your own super signature system (yunxiaoduo)?
- 有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
- How to create Apple Developer personal account P8 certificate
- 写一篇万字长文《CAS自旋锁》送杰伦的新专辑登顶热榜
- #HPDC智能基座人才发展峰会随笔
- Getting started with webgl (4)
- Yunxiaoduo software internal test distribution test platform description document
- [quick start of Digital IC Verification] 26. Ahb-sramc of SystemVerilog project practice (6) (basic points of APB protocol)
猜你喜欢
[quickstart to Digital IC Validation] 20. Basic syntax for system verilog Learning 7 (Coverage Driven... Including practical exercises)
Ida Pro reverse tool finds the IP and port of the socket server
2. Heap sort "hard to understand sort"
Write sequence frame animation with shader
Three. JS introductory learning notes 04: external model import - no material obj model
[quick start for Digital IC Validation] 26. Ahb - sramc (6) for system verilog project practice (Basic Points of APB Protocol)
【数字IC验证快速入门】22、SystemVerilog项目实践之AHB-SRAMC(2)(AMBA总线介绍)
使用Scrapy框架爬取网页并保存到Mysql的实现
【数字IC验证快速入门】20、SystemVerilog学习之基本语法7(覆盖率驱动...内含实践练习)
Gd32 F3 pin mapping problem SW interface cannot be burned
随机推荐
Use cpolar to build a business website (2)
【兰州大学】考研初试复试资料分享
The difference between full-time graduate students and part-time graduate students!
Wechat applet 01
Please supervise the 2022 plan
The download button and debug button in keil are grayed out
Three. JS introductory learning notes 00: coordinate system, camera (temporarily understood)
银行需要搭建智能客服模块的中台能力,驱动全场景智能客服务升级
How to build your own super signature system (yunxiaoduo)?
After UE4 is packaged, mesh has no material problem
15. Using the text editing tool VIM
Typescript release 4.8 beta
[deep learning] image hyperspectral experiment: srcnn/fsrcnn
有钱人买房就是不一样
Streaming end, server end, player end
Share the technical details of super signature system construction
Window环境下配置Mongodb数据库
Postman generate timestamp, future timestamp
Ida Pro reverse tool finds the IP and port of the socket server
【数字IC验证快速入门】22、SystemVerilog项目实践之AHB-SRAMC(2)(AMBA总线介绍)