当前位置:网站首页>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;
}
}
边栏推荐
- [quick start of Digital IC Verification] 22. Ahb-sramc of SystemVerilog project practice (2) (Introduction to AMBA bus)
- Steps to create P8 certificate and warehousing account
- Oracle control file loss recovery archive mode method
- Syntax of generator function (state machine)
- 20th anniversary of agile: a failed uprising
- Android -- jetpack: the difference between livedata setValue and postvalue
- A wave of open source notebooks is coming
- Use cpolar to build a business website (2)
- [original] all management without assessment is nonsense!
- 【Markdown语法高级】让你的博客更精彩(四:设置字体样式以及颜色对照表)
猜你喜欢

Async and await
![Super signature principle (fully automated super signature) [Yun Xiaoduo]](/img/b8/5bafbada054b335568e64c7e1ac6bb.jpg)
Super signature principle (fully automated super signature) [Yun Xiaoduo]

LeetCode3_ Longest substring without duplicate characters
![[quickstart to Digital IC Validation] 20. Basic syntax for system verilog Learning 7 (Coverage Driven... Including practical exercises)](/img/d3/cab8a1cba3c8d8107ce4a95f328d36.png)
[quickstart to Digital IC Validation] 20. Basic syntax for system verilog Learning 7 (Coverage Driven... Including practical exercises)

Cocos creator collision and collision callback do not take effect

After UE4 is packaged, mesh has no material problem

Super simple and fully automated generation super signature system (cloud Xiaoduo minclouds.com cloud service instance), free application in-house test app distribution and hosting platform, maintenan

Create lib Library in keil and use lib Library

Iterator and for of.. loop

【数字IC验证快速入门】25、SystemVerilog项目实践之AHB-SRAMC(5)(AHB 重点回顾,要点提炼)
随机推荐
【数字IC验证快速入门】18、SystemVerilog学习之基本语法5(并发线程...内含实践练习)
银行需要搭建智能客服模块的中台能力,驱动全场景智能客服务升级
Getting started with webgl (3)
Align individual elements to the right under flex layout
[original] all management without assessment is nonsense!
MySQL bit type resolution
[quick start of Digital IC Verification] 19. Basic grammar of SystemVerilog learning 6 (thread internal communication... Including practical exercises)
Shader Language
It's different for rich people to buy a house
Runnable是否可以中断
LeetCode2_ Add two numbers
Yunxiaoduo software internal test distribution test platform description document
Monthly observation of internet medical field in May 2022
Use cpolar to build a business website (2)
TS typescript type declaration special declaration field number is handled when the key key
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
Detailed explanation of Cocos creator 2.4.0 rendering process
Streaming end, server end, player end
[quick start of Digital IC Verification] 24. AHB sramc of SystemVerilog project practice (4) (AHB continues to deepen)
Nacos conformance protocol cp/ap/jraft/distro protocol