微信小程序集成three.js--6.利用raycastor选择对象

1.实例演示

小程序集成Three.js,利用raycaster实现对象的

2.源码

(1)引入库并声明变量

import * as THREE from '../../libs/three.weapp.js'
import {
    OrbitControls
} from '../../jsm/controls/OrbitControls'
const app = getApp()

// 声明一个二维坐标,用于设置webGl的坐标
let mouse = new THREE.Vector2()

//声明相机,场景,渲染器,控制器
let camera, scene, renderer, controls

//声明raycastor,用于进行射线检测
let raycaster = new THREE.Raycaster()

// 声明一个用于检测被raycaster射线穿过物体的几何
let INTERSECTED = null

//声明三个物体,用于射线的识别
let sphere, cylinder, cube

//声明canvas的高度,初始化时予以赋值
let canvasHeight

(2)初始化场景

onLoad: function () {
        wx.createSelectorQuery()
            .select('#webgl')
            .node()
            .exec((res) => {
                console.log(res[0])
                let canvasId = String(res[0].node.id)
                const canvas = THREE.global.registerCanvas(canvasId, res[0].node)
                canvasHeight = canvas.height
                this.setData({
                    canvasId: canvasId
                })
                //相机
                camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 1000);
                //场景
                scene = new THREE.Scene();
                scene.background = new THREE.Color(0xffffff);
                //渲染器
                renderer = new THREE.WebGLRenderer({
                    antialias: true
                });
                camera.position.set(30, 40, 90);

                //控制器
                controls = new OrbitControls(camera, renderer.domElement);
                controls.enableDamping = true;

                controls.update();

                //正方体1
                const geometry = new THREE.BoxBufferGeometry(10, 10, 10);
                const material = new THREE.MeshBasicMaterial({
                    color: 0x2a5a5
                });
                cube = new THREE.Mesh(geometry, material);
                cube.position.x = 0
                cube.name = '正方体cube'
                scene.add(cube);

                //圆球
                const sphereGeometry = new THREE.SphereGeometry(5, 20, 20)
                const sphereMaterial = new THREE.MeshBasicMaterial({
                    color: 0x341de0,
                    side: THREE.DoubleSide
                })
                sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
                sphere.position.x = 30
                sphere.name = '圆球sphere'
                scene.add(sphere)

                //柱体
                const cylinderGeometry = new THREE.CylinderGeometry(8, 8, 20, 10, 10)
                const cylinderMaterial = new THREE.MeshBasicMaterial({
                    color: 0xe1d11c,
                    side: THREE.DoubleSide
                })
                cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial)
                cylinder.position.x = -30
                cylinder.name = '圆柱cylinder'
                scene.add(cylinder)

                //平面
                const planeGeometry = new THREE.PlaneGeometry(200, 150, 20, 20);
                const planeMaterial = new THREE.MeshBasicMaterial({
                    color: 0xc7c7c7,
                    wireframe: true
                });
                planeMaterial.side = THREE.DoubleSide;
                const plane = new THREE.Mesh(planeGeometry, planeMaterial)
                plane.rotation.x = Math.PI / 2
                plane.position.y = -20
                scene.add(plane)

                //辅助线
                const axesHelper = new THREE.AxesHelper(500);
                scene.add(axesHelper)

                renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
                renderer.setSize(canvas.width, canvas.height);

                function render() {
                    canvas.requestAnimationFrame(render);
                    //更新控制器
                    controls.update();
                    renderer.render(scene, camera);
                }

                render()
            })
    },

初始化场景只是建立了3个物体.

检测点击识别物体的代码是通过绑定了canvas的 bindtouchstart 事件来实现的。

下面是wxml中<canvas>的代码  

<canvas type="webgl" id="webgl" style="width:100vw;height: 60vh;" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" bindtouchcancel="touchCancel" bindlongtap="longTap" bindtap="tap">

我们给 bindtouchstart 事件绑定了 touchStart 函数。

下面是 touchStart 函数源码

touchStart(e) {
        //console.log('canvas', e)
        THREE.global.touchEventHandlerFactory('canvas', 'touchstart')(e)
        //给mouse的x,y坐标赋值
        let x = (e.touches[0].x / wx.getWindowInfo().windowWidth) * 2 - 1;
        let y = -(e.touches[0].y / canvasHeight) * 2 + 1;
        mouse.x = x
        mouse.y = y
        raycaster.setFromCamera(mouse, camera)
        let intersects = raycaster.intersectObjects([sphere, cylinder, cube]);
        if (intersects.length > 0) {
            console.log(intersects)
            if (INTERSECTED != intersects[0].object) {
                INTERSECTED = intersects[0].object;
                console.log(INTERSECTED.name)
                wx.showToast({
                  title:INTERSECTED.name,
                  icon:'none'
                })
            }
        } else {
            INTERSECTED = null;
        }
    },

上面代码中,首先通过坐标转换,将点击屏幕的二维坐标,转换为raycastor可用的坐标。

然后将三个物体作为raycaster的检测对象。

当检测对象数组中的数量大于0,说明检测到了对象。

对象数组中第0个对象,即是我们点击的那个

3.3D模型下载及ThreeJS集成演示

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值