Skip to content

a984337740/THREE

Repository files navigation

for example: [ // import THREE from 'threejs_react';

import { THREE , CarControls , DRACOLoader , GLTFLoader , PMREMCubeUVPacker , PMREMGenerator } from 'threejs_react';

import { FormControl, FormHelperText, NativeSelect, Typography , Checkbox } from '@material-ui/core'; import * as React from 'react'; import './carshow.css';

interface IProps { a: any ; }

class CarShow extends React.Component<any, any> {

private camera ;
private scene ;
private renderer ; 
private stats ; 
private carModel;

private envMap = null;
private clock = new THREE.Clock(); 
private carControls = new CarControls();

private carParts = {
    body: [],
    rim: [],
    glass: [], 
};

private damping = 5.0;  
private distance = 5;
private cameraTarget = new THREE.Vector3();

private pmremGenerator;
private pmremCubeUVPacker;
constructor(props: IProps) {
    super(props);
    this.carControls.turningRadius = 75;
      
    this.state = {
        followCamera: false ,
        materialsLib : {
            main: [],
            glass: [],
        },
        bodySelectIndex: 0,
        rimsSelectIndex: 0,
        glassSelectIndex: 0,
    };
}

componentDidMount() {
    this.init();
   
}
 public async init() {
    const container = document.getElementById('container');

    this.camera = new THREE.PerspectiveCamera(50 , window.innerWidth / window.innerHeight , 0.1 , 200 );
    this.camera.position.set( 3.25, 2.0, - 5 );
    this.camera.lookAt( 0 , 0.5 , 0 );

    this.scene = new THREE.Scene();
    this.scene.fog = new THREE.Fog( 0xd7cbb1, 1 , 80 );
    console.log(this.scene);
    
    let light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
    light.position.set( 0, 20, 0 );
    // this.scene.add( light );

    light = new THREE.DirectionalLight( 0xffffff );
    light.position.set( 0, 20, 10 );
    // this.scene.add( light );

    const urls = [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ];
    let loader = new THREE.CubeTextureLoader();
    loader.setPath( './textures/cube/skyboxsun25deg/');

   await loader.load( urls,  (texture: any) =>  {
        console.log(texture);

        this.scene.background = texture;
        console.log(this.scene);
        this.pmremGenerator = new PMREMGenerator( texture );
        this.pmremGenerator.update( this.renderer );

        this.pmremCubeUVPacker = new PMREMCubeUVPacker( this.pmremGenerator.cubeLods );
        this.pmremCubeUVPacker.update( this.renderer );
        console.log(this.pmremCubeUVPacker.CubeUVRenderTarget.texture);
        this.envMap = this.pmremCubeUVPacker.CubeUVRenderTarget.texture;
console.log(this.envMap);
       this.pmremGenerator.dispose();
        this.pmremCubeUVPacker.dispose();
       
        this.initCar();
        this.initMaterials();

   });
    console.log(loader);

    let grid = new THREE.GridHelper(400 , 40 , 0x000000, 0x000000);
    grid.material.opacity = 0.2;
    grid.material.depthWrite = false;
    grid.material.transparent = true;
    this.scene.add(grid);

    this.renderer = new THREE.WebGLRenderer( { antialias: true } );
    this.renderer.gammaOutput = true;
    this.renderer.setPixelRatio( window.devicePixelRatio );
    this.renderer.setSize( window.innerWidth, window.innerHeight );
    console.log(this.camera);
    console.log(this.renderer);
    container.appendChild( this.renderer.domElement );
    
    window.addEventListener( 'resize', this.onWindowResize , false );
    this.animation();
}

private onWindowResize = () => {
    this.camera.aspect = (window.innerWidth / window.innerHeight); 
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    console.log(window.innerWidth, window.innerHeight);
    console.log( document.body.clientWidth  , document.body.clientHeight);
}

 private  initCar() {
    DRACOLoader.setDecoderPath( '/js/libs/draco/gltf/' );

    const loader = new GLTFLoader();
    loader.setDRACOLoader( new DRACOLoader() );
     loader.load( '/models/gltf/ferrari.glb', ( gltf: any ) => {
         
        console.log( gltf.scene.children[ 0 ]);
        this.carModel = gltf.scene.children[ 0 ];
    
        this.carControls.setModel(  this.carModel , null );
    
        this.carModel.traverse(  ( child: any ) => {
    
            if ( child.isMesh ) {

                child.material.envMap =  this.envMap;        
            }
    
        } );
    
        // shadow
        const texture = new THREE.TextureLoader().load( '/models/gltf/ferrari_ao.png' );
        const shadow = new THREE.Mesh(
            new THREE.PlaneBufferGeometry( 0.655 * 4, 1.3 * 4 ).rotateX( - Math.PI / 2 ),
            new THREE.MeshBasicMaterial( { map: texture, opacity: 0.8, transparent: true } )
        );
        shadow.renderOrder = 2;
        this.carModel.add( shadow );
    
        this.scene.add( this.carModel );
    
        // car parts for material selection
        this. carParts.body.push( this.carModel.getObjectByName( 'body' ) );
    
        this.carParts.rim.push(
            this.carModel.getObjectByName( 'rim_fl' ),
            this.carModel.getObjectByName( 'rim_fr' ),
            this.carModel.getObjectByName( 'rim_rr' ),
            this. carModel.getObjectByName( 'rim_rl' ),
            this.carModel.getObjectByName( 'trim' ),
        );
    
        this.carParts.glass.push(
            this.carModel.getObjectByName( 'glass' ),
         );
    
         this.updateMaterials();
     }) ;

}

private initMaterials() {
    let materialsLib = {
            main: [
            new THREE.MeshStandardMaterial( { 
                                        color: 0xff4400, envMap: this.envMap, metalness: 0.9, roughness: 0.2, name: 'orange' } ),
            new THREE.MeshStandardMaterial( { 
                                        color: 0x001166, envMap: this.envMap, metalness: 0.9, roughness: 0.2, name: 'blue' } ),
            new THREE.MeshStandardMaterial( {
                                        color: 0x990000, envMap: this.envMap, metalness: 0.9, roughness: 0.2, name: 'red' } ),
            new THREE.MeshStandardMaterial( { 
                                        color: 0x000000, envMap: this.envMap, metalness: 0.9, roughness: 0.5, name: 'black' } ),
            new THREE.MeshStandardMaterial( { 
                                        color: 0xffffff, envMap: this.envMap, metalness: 0.9, roughness: 0.5, name: 'white' } ),
            new THREE.MeshStandardMaterial( { 
                                        color: 0x555555, envMap: this.envMap, envMapIntensity: 2.0, metalness: 1.0, 
                                        roughness: 0.2, name: 'metallic' } ),
            ],
            glass: [

            new THREE.MeshStandardMaterial( { 
                                        color: 0xffffff, envMap: this.envMap, metalness: 1, roughness: 0,
                                        // tslint:disable-next-line: max-line-length
                                        opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'clear' } ),
            new THREE.MeshStandardMaterial( { 
                                        color: 0x000000, envMap: this.envMap, metalness: 1, roughness: 0,
                                         // tslint:disable-next-line: max-line-length
                                        opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'smoked' } ),
            new THREE.MeshStandardMaterial( { 
                                        color: 0x001133, envMap: this.envMap, metalness: 1, roughness: 0,
                                        opacity: 0.2, transparent: true, premultipliedAlpha: true, name: 'blue' } ),
            ],
        };
        this.setState({
            materialsLib: materialsLib
        });                    
}

private updateMaterials() {
    const e1 = {target: {value: 3}};
    this.handleChange(e1);
    const e2 = {target: {value: 5}};
    this.handleRimsChange(e2);
    const e3 = {target: {value: 0}};
    this.handleGlassChange(e3);
}
private animation() {                 
    this.update();
    requestAnimationFrame(() => this.animation());
}    

private update() {                 
   const delta = this.clock.getDelta();
   const {followCamera} = this.state;
   if ( this.carModel ) {
    this.carControls.update(delta / 3);

       if ( this.carModel.position.length() > 200 ) {
        this.carModel.position.set(0, 0 , 0);
        this.carControls.speed = 0;
       }

       if ( followCamera ) {
        this.carModel.getWorldPosition( this.cameraTarget );
        this.cameraTarget.y = 2.5;
        this.cameraTarget.z += this.distance;

           this.camera.position.lerp( this.cameraTarget , delta * this.damping );
       } else {

           this.carModel.getWorldPosition( this.cameraTarget );
           this.cameraTarget.y += 0.5;

           this.camera.position.set( 3.25, 2.0, - 5 );

       }
       this.camera.lookAt( this.carModel.position );
   }
   this.renderer.render(this.scene , this.camera);
}    

handleChange(event: any) {
    console.log(event);
    const bodyMat = this.state.materialsLib.main[ event.target.value ];
    this.setState({
        bodySelectIndex: event.target.value
    });
    this.carParts.body.forEach( part => part.material = bodyMat );
}
// 渲染车身颜色下拉列表
public renderBodyColor() { 
    return (
        <Typography component="span">
        车身颜色:       
        <FormControl className={' '}>
        <NativeSelect
          value={this.state.bodySelectIndex}
          onChange={(event) => this.handleChange(event)}
          name="age"
          className={''}
          inputProps={{ 'aria-label': 'age' }}
        >
            {this.state.materialsLib.main.map( (val , index) => {
                return(
                    <option value={index} key = {index}>{val.name}</option>
                );
            })}              
        </NativeSelect>
        <FormHelperText>Body Color</FormHelperText>
      </FormControl>
      </Typography>
    );
}
// 细节选择的点击事件
handleRimsChange(event: any) {
    console.log(event);

    const bodyMat = this.state.materialsLib.main[ event.target.value ];
    this.setState({
        rimsSelectIndex: event.target.value
    });
    this.carParts.rim.forEach( part => part.material = bodyMat );
}
// 渲染细节颜色下拉列表
public renderRimsColor() {
    return (
        <Typography component="span">
        细节颜色:           
        <FormControl className={' '}>
        <NativeSelect
          value={this.state.rimsSelectIndex}
          onChange={(event) => this.handleRimsChange(event)}
          name="age"
          className={''}
          inputProps={{ 'aria-label': 'age' }}
        >
            {this.state.materialsLib.main.map( (val , index) => {
                return(
                    <option value={index} key = {index}>{val.name}</option>
                );
            })}              
        </NativeSelect>
        <FormHelperText>Rims Color</FormHelperText>
      </FormControl>
      </Typography>
    );
}
    // 玻璃选择的点击事件
    handleGlassChange(event: any) {
    console.log(event);

        const bodyMat = this.state.materialsLib.glass[ event.target.value ];
        this.setState({
            glassSelectIndex: event.target.value
        });
        this.carParts.glass.forEach( part => part.material = bodyMat );
    }
    // 渲染玻璃颜色下拉列表
    public renderGlassColor() {
        return (
            <Typography component="span">
            玻璃颜色:       
            <FormControl className={' '}>
            <NativeSelect
              value={this.state.glassSelectIndex}
              onChange={(event) => this.handleGlassChange(event)}
              name="age"
              className={''}
              inputProps={{ 'aria-label': 'age' }}
            >
                {this.state.materialsLib.glass.map( (val , index) => {
                    return(
                        <option value={index} key = {index}>{val.name}</option>
                    );
                })}              
            </NativeSelect>
            <FormHelperText>Glass Color</FormHelperText>
          </FormControl>
          </Typography>
        );
    }

    handleCheckChange(event: any) {
        const val = !this.state.followCamera;
        this.setState({
            followCamera: val,
        });
    }
    renderCheckBox() {
        return(
            <Checkbox
            checked={this.state.followCamera}
            onChange= {(event) => this.handleCheckChange(event)}
            value="checkedA"
            inputProps={{
              'aria-label': 'primary checkbox',
            }}
          />
        );
    }
public render() {
    return(
        <div>           
                汽车测试   
             {this.renderBodyColor()}  
             {this.renderRimsColor()}
             {this.renderGlassColor()}
             {this.renderCheckBox()}
            <div id = "container" className = "pos">               
                        
                        </div>
        </div>
       
    );
}

}

export default CarShow ; ]

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages