three.js物体按照轨迹行走并显示轨迹
人物按照指定个轨迹行走
显示人物行走的轨迹
核心代码
时间有限,核心代码如下,没时间解释,敬请原谅。
var curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-6, 0, -5),
new THREE.Vector3(-6, 0, -10),
new THREE.Vector3(10, 0, -5),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(-6, 0, -3),
new THREE.Vector3(-3, 0, -7),
new THREE.Vector3(10, 0, -5)
], false/*是否闭合*/);
var tubeGeometry = new THREE.TubeGeometry(curve, 100, 0.1, 50, false);
var tubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: false })
var tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
var points = curve.getPoints(3000);
var _material = new THREE.LineBasicMaterial({
color: 0xff0000
});
var _geometry = new THREE.BufferGeometry();
var _pointsBuf = [
// 10,0,0,
// 0,0,10,
]
var _vertices = new Float32Array(_pointsBuf);
_geometry.addAttribute('position', new THREE.BufferAttribute(_vertices, 3));
var _lineA = new THREE.Line(_geometry, _material);
scene.add(_lineA);
let _i = 0;;
setTimeout(() => {
setInterval(() => {
_pointsBuf.push(points[_i].x, points[_i].y, points[_i].z)
_vertices = new Float32Array(_pointsBuf)
_geometry.addAttribute('position', new THREE.BufferAttribute(_vertices, 3));
renwu.position.set(points[_i].x, points[_i].y, points[_i].z);
renwu.lookAt(points[_i+1].x, points[_i+1].y, points[_i+1].z)
_i++;
if(_i>3000-1) _i=0
}, 10);
}, 3000);
人物模型
哎,还有人要模型,模型在下面连接,自己下载。 walkingman.fbx
全部代码
还有人非得要全部代码,也是醉了。 下面就是
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="JS/three.js"></script>
<script src="js/WebGL.js"></script>
<script src="JS/MTLLoader.js"></script>
<script src="JS/OBJLoader.js"></script>
<script src="JS/OrbitControls.js"></script>
<script src="JS/Tween.js"></script>
<script src="JS/inflate.min.js"></script>
<script src="JS/FBXLoader.js"></script>
<script src="JS/CSS2DRenderer.js"></script>
</head>
<body>
<script>
if (WEBGL.isWebGLAvailable() === false) {
document.body.appendChild(WEBGL.getWebGLErrorMessage());
}
//创建场景,相机,渲染器,网格
var scene, camera, renderer, controls, tween, mesh, mixer;
var meshfloor;
var keyboard = {};
var player = { height: 1.8, speed: 0.2, turnSpeed: Math.PI * 0.05 };
var renwu;
var flag = false;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(90, 1280 / 720, 0.1, 100);
var clock = new THREE.Clock();
var target;
var spherical = new THREE.Spherical();
var rotationMatrix = new THREE.Matrix4();
var targetRotation = new THREE.Quaternion();
// var clock = new THREE.Clock();
var speed = 2;
//红点
var targetGeometry = new THREE.SphereBufferGeometry(0.5);
var targetMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
target = new THREE.Mesh(targetGeometry, targetMaterial);
scene.add(target);
meshfloor = new THREE.Mesh(
new THREE.PlaneGeometry(20, 20, 10, 10),
new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: false })
)
var geometry = new THREE.PlaneGeometry(20, 20, 10, 10);//矩形平面
var texture = new THREE.ImageUtils.loadTexture("floor.jpg");//加载纹理贴图
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //重复包装
texture.repeat.set(20, 20);//重复个数
var material = new THREE.MeshLambertMaterial({
map: texture,//给纹理属性map赋值
side: THREE.DoubleSide//两面可见
});//材质对象
meshfloor = new THREE.Mesh(geometry, material);//纹理贴图网格模型对象
meshfloor.rotation.x -= Math.PI / 2;
// scene.add(mesh);
scene.add(meshfloor);
var models = [];
var loader = new THREE.FBXLoader();
loader.load("walkingman.fbx", function (object) {
mixer = new THREE.AnimationMixer(object);
var action = mixer.clipAction(object.animations[0]);
action.play();
object.traverse(function (child) {
if (child.isMesh) {
child.castShadow = true;
child.receiveShadow = true;
}
});
object.rotation.y = 1.57;
// object.rotation.x = -1.57;
renwu = new THREE.Group();
renwu.add(object)
scene.add(renwu);
console.log(renwu);
});
//辅助线
var axes = new THREE.AxisHelper(20);
scene.add(axes);
var curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-6, 0, -5),
new THREE.Vector3(-6, 0, -10),
new THREE.Vector3(10, 0, -5),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(-6, 0, -3),
new THREE.Vector3(-3, 0, -7),
new THREE.Vector3(10, 0, -5)
], false/*是否闭合*/);
var tubeGeometry = new THREE.TubeGeometry(curve, 100, 0.1, 50, false);
var tubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: false })
var tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
// scene.add(tube)
var points = curve.getPoints(3000);
var _material = new THREE.LineBasicMaterial({
color: 0xff0000
});
var _geometry = new THREE.BufferGeometry();
var _pointsBuf = [
// 10,0,0,
// 0,0,10,
]
var _vertices = new Float32Array(_pointsBuf);
_geometry.addAttribute('position', new THREE.BufferAttribute(_vertices, 3));
var _lineA = new THREE.Line(_geometry, _material);
scene.add(_lineA);
let _i = 0;
console.log('renwu :', renwu);
setTimeout(() => {
console.log('renwu :', renwu);
setInterval(() => {
_pointsBuf.push(points[_i].x, points[_i].y, points[_i].z)
_vertices = new Float32Array(_pointsBuf)
_geometry.addAttribute('position', new THREE.BufferAttribute(_vertices, 3));
renwu.position.set(points[_i].x, points[_i].y, points[_i].z);
renwu.lookAt(points[_i+1].x, points[_i+1].y, points[_i+1].z)
_i++;
if(_i>3000-1) _i=0
}, 10);
}, 3000);
//环境光
ambientLight = new THREE.AmbientLight(0xffffff, 0.3);
scene.add(ambientLight);
//点光
light = new THREE.PointLight(0xffffff, 0.9, 250);
light.position.set(0, 20, -10);
light.castShadow = true;
light.shadow.camera.near = 0.1;
light.shadow.camera.far = 25;
scene.add(light);
camera.position.set(0, player.height, -5);
camera.lookAt(new THREE.Vector3(0, player.height, 0));
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0x4682B4, 1.0);
renderer.setSize(1280, 720);
createHtml("img", "person.png", "person", "点击就能成神", 20);
createHtml("img", "fps.png", "fps", "点击就能成神", -10);
createHtml("img", "reset.png", "reset", "点击就能成神", -40);
function createHtml(img, src, className, text, extend) {
var laberDiv = document.createElement("img");
laberDiv.src = src;
laberDiv.onclick = function () { bnt1(className); };
laberDiv.className = className;
laberDiv.textContent = text;
laberDiv.setAttribute('align', 'center');
laberDiv.style.marginTop = '-1em';
var pointLabel = new THREE.CSS2DObject(laberDiv);
pointLabel.position.set(0, extend, 50);
scene.add(pointLabel);
}
labelRenderer = new THREE.CSS2DRenderer(); //新建CSS2DRenderer
labelRenderer.setSize(40, 120);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.margin = '10px';
labelRenderer.domElement.style.background = '#FFFFFF';
console.log(labelRenderer.domElement.style);
document.body.appendChild(labelRenderer.domElement);
renderer.render(scene, camera);
labelRenderer.render(scene, camera);//渲染
function bnt1(className) {
if (className === 'person') {
if (flag === false) {
mixer._actions[0].play();
flag = true;
}
else {
flag = false;
mixer._actions[0].stop();
}
}
}
//把画面插入HTML中的body标签下显示
document.body.appendChild(renderer.domElement);
initControls();
animate();
var progress = 0;
function animate() {
requestAnimationFrame(animate);
// mesh.rotation.x+=0.01;
// mesh.rotation.y+=0.02;
controls.update();
TWEEN.update();
var delta = clock.getDelta();
if (mixer) mixer.update(delta);
renderer.render(scene, camera);
}
function keyDown(event) {
keyboard[event.keyCode] = true;
}
function keyUp(event) {
keyboard[event.keyCode] = false;
}
function initControls() {
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enableZoom = true;
controls.autoRotate = false;
controls.autoRotateSpeed = 0.5;
controls.minDistance = 1;
controls.maxDistance = 2000;
controls.enablePan = true;
}
function generateTarget() {
spherical.theta = Math.random() * Math.PI * 2;
spherical.phi = Math.acos((2 * Math.random()) - 1);
spherical.radius = 2;
target.position.setFromSpherical(spherical);
// compute target rotation
//计算目标旋转
rotationMatrix.lookAt(target.position, renwu.position, renwu.up);
targetRotation.setFromRotationMatrix(rotationMatrix);
setTimeout(generateTarget, 3000);
}
window.addEventListener('keydown', keyDown);
window.addEventListener(('keyup'), keyUp);
</script>
</body>
</html>
CatmullRomCurve3
是 Three.js 中的一种曲线类型,用于创建 Catmull-Rom 样条曲线。Catmull-Rom 样条曲线是一种平滑的曲线,它通过一组控制点来定义曲线的形状。与贝塞尔曲线不同,Catmull-Rom 曲线可以通过控制点的位置和切线来精确控制曲线的形状。
在 Three.js 中创建 CatmullRomCurve3 很简单,只需要创建一个 CatmullRomCurve3 类的实例,并将控制点添加到曲线中即可。例如:
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)
]);
在上述代码中,我们创建了一个 CatmullRomCurve3 曲线,其中包含了五个控制点。这些控制点用于定义曲线的形状。
除了控制点之外,CatmullRomCurve3 还有一些其他的属性和方法,可以用于控制曲线的细节。例如:
- curve.points:获取或设置曲线的控制点数组。
- curve.closed:获取或设置曲线是否闭合。
- curve.getPoint(t):获取曲线上 t 位置处的点坐标。
- curve.getTangent(t):获取曲线上 t 位置处的切向量。
- curve.getLength():获取曲线的长度。
通过这些属性和方法,我们可以更加精确地控制 Catmull-Rom 曲线的形状和行为。
TubeGeometry
TubeGeometry 是 Three.js 中的一种几何体类型,用于创建管道状几何体。TubeGeometry 的构造函数接受两个参数:一个路径和一个半径。路径是一个 Curve 类型的对象,用于定义管道的路径;半径是一个数值类型的值,用于定义管道的半径。
在 Three.js 中创建 TubeGeometry 很简单,只需要创建一个 TubeGeometry 类的实例,并将路径和半径作为参数传入即可。例如:
var path = new THREE.CatmullRomCurve3([
new THREE.Vector3(-10, 0, 0),
new THREE.Vector3(-5, 5, 5),
new THREE.Vector3(0, 0, 10),
new THREE.Vector3(5, -5, 5),
new THREE.Vector3(10, 0, 0)
]);
var radius = 1;
var tubeGeometry = new THREE.TubeGeometry(path, 64, radius, 16, false);
在上述代码中,我们创建了一个路径对象和一个半径值,并将它们作为参数传入 TubeGeometry 的构造函数中。我们还设置了一些其他的参数,例如管道的分段数、半径的分段数以及是否闭合管道等。
除了上述参数之外,TubeGeometry 还有一些其他的属性和方法,可以用于控制管道的细节。例如:
- tubeGeometry.parameters.path:获取管道的路径对象。
- tubeGeometry.parameters.radius:获取管道的半径。
- tubeGeometry.getPoint(t):获取管道上 t 位置处的点坐标。
- tubeGeometry.getTangent(t):获取管道上 t 位置处的切向量。
通过这些属性和方法,我们可以更加精确地控制 TubeGeometry 的形状和行为。