当前位置:网站首页>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;
}
}
边栏推荐
- LeetCode2_ Add two numbers
- Unity's ASE realizes cartoon flame
- Monthly observation of internet medical field in May 2022
- [quickstart to Digital IC Validation] 20. Basic syntax for system verilog Learning 7 (Coverage Driven... Including practical exercises)
- Ue4/ue5 multi thread development attachment plug-in download address
- Async and await
- 全日制研究生和非全日制研究生的区别!
- Typescript release 4.8 beta
- Steps to create P8 certificate and warehousing account
- [markdown grammar advanced] make your blog more exciting (IV: set font style and color comparison table)
猜你喜欢

Mesh merging under ue4/ue5 runtime

写一篇万字长文《CAS自旋锁》送杰伦的新专辑登顶热榜

Keil5 does not support online simulation of STM32 F0 series

OpenGL's distinction and understanding of VAO, VBO and EBO

Create lib Library in keil and use lib Library

Cocos creator collision and collision callback do not take effect
![[quick start of Digital IC Verification] 29. Ahb-sramc (9) (ahb-sramc svtb overview) of SystemVerilog project practice](/img/f7/03975d08912afd8daee936799e8951.png)
[quick start of Digital IC Verification] 29. Ahb-sramc (9) (ahb-sramc svtb overview) of SystemVerilog project practice

Three. JS introductory learning notes 04: external model import - no material obj model

2. Heap sort "hard to understand sort"

Zhongang Mining: Fluorite continues to lead the growth of new energy market
随机推荐
[wechat applet] Chapter (5): basic API interface of wechat applet
Using eating in cocos Creator
【Markdown语法高级】让你的博客更精彩(四:设置字体样式以及颜色对照表)
【數字IC驗證快速入門】20、SystemVerilog學習之基本語法7(覆蓋率驅動...內含實踐練習)
Share the technical details of super signature system construction
【数字IC验证快速入门】18、SystemVerilog学习之基本语法5(并发线程...内含实践练习)
The "go to definition" in VS2010 does not respond or prompts the solution of "symbol not found"
[quick start for Digital IC Validation] 26. Ahb - sramc (6) for system verilog project practice (Basic Points of APB Protocol)
Write sequence frame animation with shader
一大波开源小抄来袭
MongoDB数据库基础知识整理
How to release NFT in batches in opensea (rinkeby test network)
有钱人买房就是不一样
Tkinter after how to refresh data and cancel refreshing
[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
TS typescript type declaration special declaration field number is handled when the key key
[original] all management without assessment is nonsense!
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
Yunxiaoduo software internal test distribution test platform description document
Excerpted words