Babylonjs学习笔记(一)——搭建基础场景

React + typescript + umi + Babylonjs 搭建基础场景

yarn add --save babylonjs babylonjs-loaders

1、封装基础场景
import { Engine, Scene } from "babylonjs";
import { useEffect,useRef,FC } from "react";
import "./index.less"

type PropsType = {
  antalias:any;
  engineOptions?:any;
  adaptToDeviceRatio?:any;
  sceneOptions?:any;
  onRender:(scene:Scene)=>void;
  onSceneReady:any;
  [key:string]:any;
}

const BaseScene:FC<PropsType>=(props)=>{
  const {antalias,engineOptions,adaptToDeviceRatio,sceneOptions,onRender,onSceneReady,...rests} = props

  // 获取canvas画布
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(()=>{

    const {current:canvas} = canvasRef
    if(!canvas)return

    
    // 创建babylonjs 引擎
    const engine = new Engine(canvas,antalias,engineOptions  ,adaptToDeviceRatio);
    // 创建场景
    const scene = new Scene(engine,sceneOptions)
    
    // 搭建场景
    if(scene.isReady()){
      onSceneReady(scene)
    }else{
      scene.onReadyObservable.addOnce((scene)=>onSceneReady(scene))
    }

    // 帧渲染
    engine.runRenderLoop(()=>{
      if(typeof onRender === 'function') onRender?.(scene);
      scene?.render();
    })
    
    const resize=()=>{
      scene.getEngine().resize()
    }
    // 监听画布大小
    if(window){
      window.addEventListener('resize',resize)
    }
    // 销毁
    return ()=>{
      scene.getEngine().dispose()
      if(window){
        window.removeEventListener('resize',resize)
      }
    }
  },[antalias,engineOptions,adaptToDeviceRatio,sceneOptions,onRender,onSceneReady])
  
  return <canvas ref={canvasRef} className="renderCanvas" {...rests}/>
}
export default BaseScene

2、封装应用场景
import {  ArcRotateCamera, HemisphericLight, MeshBuilder, Scene,  Vector3 } from "babylonjs";
import 'babylonjs-loaders'
import BaseScene from "./BaseScene";


let box:any;
const onSceneReady=async (scene:Scene)=>{
  
  // 创建相机
  const camera = new ArcRotateCamera('camera',0,0.8,100,Vector3.Zero(),scene)

  // 设置相机目标
  camera.setTarget(Vector3.Zero());

  // 获取画布
  const canvas = scene.getEngine().getRenderingCanvas();

  // 添加控制器
  camera.attachControl(canvas,true);

  // 框架行为
  camera.useFramingBehavior =true;

  // 添加灯光
  const light = new HemisphericLight('light',new Vector3(0,1,0),scene)

  // 设置强度
  light.intensity = 0.7;

  // 创建box
  box = MeshBuilder.CreateBox('box',{size:2},scene)
  box.position.y= 1;

  // 相机目标
  camera.setTarget(box)

  MeshBuilder.CreateGround('ground',{width:6,height:6},scene)
}




const onRender=(scene:Scene)=>{
  if(box !== undefined){
    const deltTime = scene.getEngine().getDeltaTime();

    const rpm = 10;
    box.rotation.y += (rpm / 60) * Math.PI * 2 * (deltTime / 1000);
  }
}

export default ()=>
    <BaseScene  antalias onSceneReady={onSceneReady} onRender={onRender} id="canvas" />
3、应用场景
import BaseScene from '@/components/Robot';
import { PageContainer } from '@ant-design/pro-components';
import styles from './index.less';

const HomePage: React.FC = () => {
  return (
    <PageContainer ghost>
      <div className={styles.container}>
       <BaseScene />
      </div>
    </PageContainer>
  );
};

export default HomePage;
4、演示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superTiger_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值