react-three-renderer icon indicating copy to clipboard operation
react-three-renderer copied to clipboard

Implement missing internal components

Open toxicFork opened this issue 8 years ago • 14 comments

  • [ ] Objects
    • [ ] Meshes
      • [ ] Bone
      • [ ] LensFlare
      • [ ] LineSegments
      • [ ] LOD
      • [ ] MorphAnimMesh
      • [ ] SkinnedMesh
      • [ ] Skeleton
      • [x] Sprite
    • [ ] Lights
      • [ ] HemisphereLight
      • [ ] Light
    • [ ] Helpers
      • [ ] BoundingBoxHelper
      • [ ] BoxHelper
      • [ ] DirectionalLightHelper
      • [ ] EdgesHelper
      • [ ] FaceNormalsHelper
      • [ ] GridHelper
      • [ ] HemisphereLightHelper
      • [ ] PointLightHelper
      • [ ] SpotLightHelper
      • [ ] VertexNormalsHelper
      • [ ] WireframeHelper
  • [ ] Materials
    • [ ] Material
    • [ ] MeshFaceMaterial
    • [x] RawShaderMaterial
    • [ ] SpriteCanvasMaterial
    • [x] SpriteMaterial
  • [ ] Textures
    • [ ] CubeTexture
    • [ ] CompressedTexture
    • [ ] DataTexture
  • [ ] Geometries
    • [x] CubeGeometry
    • [x] DodecahedronGeometry
    • [x] PlaneGeometry
    • [x] PolyhedronGeometry
    • [ ] ShapeGeometry
    • [x] TextGeometry
    • [x] TubeGeometry
  • [ ] Shapes
    • [ ] Curve
    • [ ] CurvePath
    • [ ] Gyroscope
    • [ ] Path

toxicFork avatar Oct 27 '15 09:10 toxicFork

how should we start? :)

baopham avatar Feb 14 '16 02:02 baopham

Good question and thanks for your interest! I will write a guide when I have some time an evening or during the weekend :)

toxicFork avatar Feb 14 '16 09:02 toxicFork

Here's a draft ( I will add a better one to the wiki when I have more time ):

How to add new components

First of all, this will be a difficult task in the beginning.

I recommend looking at other components to see how they do things.

This is how I would add TextGeometry:

  • Create TextGeometryDescriptor.js in src/lib/descriptors/Geometry/:
import THREE from 'three';

import GeometryDescriptorBase from './GeometryDescriptorBase';

class TextGeometryDescriptor extends GeometryDescriptorBase {
  constructor(react3RendererInstance) {
    super(react3RendererInstance);

    // add prop declarations here
  }

  construct(props) {
    // props from http://threejs.org/docs/#Reference/Extras.Geometries/TextGeometry:
    const {
      text, // string

      font, // THREE.Font
      size, // number
      height, // number
      curveSegments, // number
      bevelEnabled, // bool
      bevelThickness, // number
      bevelSize, // number
    } = props;

    return new THREE.TextGeometry(text, {
      font,
      size,
      height,
      curveSegments,
      bevelEnabled,
      bevelThickness,
      bevelSize,
    });
  }
}

module.exports = TextGeometryDescriptor;

To add the props,


import PropTypes from 'react/lib/ReactPropTypes';

And then, for each prop, you can use this.hasProp(name, info).

  • The name property is what the component will accept
  • The info property has:
    • type : The PropType for that property

    • simple : If true, when the prop is present, it will update it directly on the created THREE object.

      • For example, a material opacity property is simple, it will behave as material.opacity = new value.
      • With simple === true, if a default property is set, then when the property is removed from the component, this value will be assigned to the object.
    • If simple is false:

    • update: how to update the object once the property is changed.

      The parameters are: ( THREE object, new prop value )

      For example, material.alphaTest property description is:

      
        this.hasProp('alphaTest', {
          type: PropTypes.number,
          updateInitial: true,
          update: (material, alphaTest) => {
            material.alphaTest = alphaTest;
            material.needsUpdate = true;
          },
        });
      
    • updateInitial: Should update be called when the object is constructed?

    • default: The value that will be passed into update if the property is deleted from the component.

TextGeometryDescriptor props:

  • text: type is string, and it's required, and I think the geometry will need to be re-constructed when this property changes. To force a reconstruction of the component, you can use this.triggerRemount. Such is magic. Since it will force re-construction, and it will be passed onto the constructor of TextGeometry, then updateInitial does not need to be set. let's make the default to be 'TEXT MISSING' to be extra helpful:

    
      this.hasProp('text', {
        type: PropTypes.string.isRequired,
        update: this.triggerRemount,
        default: 'TEXT MISSING',
      });
    
  • font: type is THREE.Font, required, will trigger remount. We can't have a default, sadly:

    
      this.hasProp('font', {
        type: PropTypes.instanceOf(THREE.Font).isRequired,
        update: this.triggerRemount,
      });
    
  • size: number, required, will trigger remount. No default as it's required:

    
      this.hasProp('size', {
        type: PropTypes.number.isRequired,
        update: this.triggerRemount,
      });
    
  • height: number, not required, will trigger remount, default is 50 from http://threejs.org/docs/#Reference/Extras.Geometries/TextGeometry:

    
      this.hasProp('height', {
        type: PropTypes.number,
        update: this.triggerRemount,
        default: 50,
      });
    
  • And so on:

      this.hasProp('curveSegments', {
        type: PropTypes.number,
        update: this.triggerRemount,
        default: 12,
      });
    
      this.hasProp('bevelEnabled', {
        type: PropTypes.bool,
        update: this.triggerRemount,
        default: false,
      });
    
      this.hasProp('bevelThickness', {
        type: PropTypes.bool,
        update: this.triggerRemount,
        default: 10,
      });
    
      this.hasProp('bevelSize', {
        type: PropTypes.bool,
        update: this.triggerRemount,
        default: 8,
      });
    

Here's the completed file:

import THREE from 'three';

import GeometryDescriptorBase from './GeometryDescriptorBase';

import PropTypes from 'react/lib/ReactPropTypes';

class TextGeometryDescriptor extends GeometryDescriptorBase {
  constructor(react3RendererInstance) {
    super(react3RendererInstance);

    this.hasProp('text', {
      type: PropTypes.string.isRequired,
      update: this.triggerRemount,
      default: 'TEXT MISSING',
    });

    this.hasProp('font', {
      type: PropTypes.instanceOf(THREE.Font).isRequired,
      update: this.triggerRemount,
    });

    this.hasProp('size', {
      type: PropTypes.number.isRequired,
      update: this.triggerRemount,
    });

    this.hasProp('height', {
      type: PropTypes.number,
      update: this.triggerRemount,
      default: 50,
    });

    this.hasProp('curveSegments', {
      type: PropTypes.number,
      update: this.triggerRemount,
      default: 12,
    });

    this.hasProp('bevelEnabled', {
      type: PropTypes.bool,
      update: this.triggerRemount,
      default: false,
    });

    this.hasProp('bevelThickness', {
      type: PropTypes.bool,
      update: this.triggerRemount,
      default: 10,
    });

    this.hasProp('bevelSize', {
      type: PropTypes.bool,
      update: this.triggerRemount,
      default: 8,
    });
  }

  construct(props) {
    // props from http://threejs.org/docs/#Reference/Extras.Geometries/TextGeometry:
    const {
      text, // string

      font, // THREE.Font
      size, // number
      height, // number
      curveSegments, // number
      bevelEnabled, // bool
      bevelThickness, // number
      bevelSize, // number
    } = props;

    return new THREE.TextGeometry(text, {
      font,
      size,
      height,
      curveSegments,
      bevelEnabled,
      bevelThickness,
      bevelSize,
    });
  }
}

module.exports = TextGeometryDescriptor;

Let's add this component to ElementDescriptorContainer, this is the final step for implementation:


import TextGeometryDescriptor from './descriptors/Geometry/TextGeometryDescriptor';

this.descriptors = {
      // ...
      extrudeGeometry: new ExtrudeGeometryDescriptor(react3RendererInstance),
      textGeometry: new TextGeometryDescriptor(react3RendererInstance),
      // ...
};

Now you should be able to use <textGeometry/> ( after the PR is approved and merged) :)

BUT WAIT

Let's generate documentation for it as well!

In \docs\src\internalComponentCategories.js, we need to remove the TODO for TextGeometry in Geometries.TODO, and add it to Geometries.children underneath extrudeGeometry.

If we run gulp doc now, it should create the file for \docs\src\internalComponents\textGeometry.js.

In there, you can populate the intro, the description and properties:

import DocInfo from '../DocInfo';

class textGeometry extends DocInfo {
  getIntro() {
    return `Creates a [THREE.TextGeometry](http://threejs.org/docs/#Reference/Extras.Geometries/TextGeometry)`;
  }

  getDescription() {
    return '';
  }

  getAttributesText() {
    return {
      dynamic: '',
      name: '',
      resourceId: '',
      text: 'The text that needs to be shown.',
      font: 'The font for the text.',
      size: 'The size of the text.',
      height: 'The thickness to extrude text. Default is 50.',
      curveSegments: 'The number of points on the curves. Default is 12.',
      bevelEnabled: 'Turn on bevel. Default is false.',
      bevelThickness: 'How deep into text bevel goes. Default is 10.',
      bevelSize: 'How far from text outline is bevel. Default is 8.',
    };
  }
}

module.exports = textGeometry;

Now it should also appear in the wiki!

Testing: In another guide.

  • [x] Add basic descriptor guide
  • [x] Add basic documentation guide
  • [ ] Add CONTRIBUTING.md
  • [ ] Add Testing guide

toxicFork avatar Feb 21 '16 16:02 toxicFork

Here's an example PR: https://github.com/toxicFork/react-three-renderer/pull/30

toxicFork avatar Feb 21 '16 16:02 toxicFork

Just noticed that getDescription should have been empty and I should have used getIntro instead, fixed in the comment above :)

toxicFork avatar Feb 24 '16 18:02 toxicFork

oh shoot. Thanks, I'll update and send another PR

baopham avatar Feb 24 '16 18:02 baopham

No need! I fixed them during the merge of your PRs :)

On 24 February 2016 at 18:19, Bao Pham [email protected] wrote:

oh shoot. Thanks, I'll update and send another PR

— Reply to this email directly or view it on GitHub https://github.com/toxicFork/react-three-renderer/issues/2#issuecomment-188389857 .

toxicFork avatar Feb 24 '16 18:02 toxicFork

thanks!

baopham avatar Feb 24 '16 18:02 baopham

Here is a list of new objects since r80. Note: I don't know if you want to support all buffer geometries ?

Geometries:

  • [ ] ConeGeometry

Buffer Geometries:

  • [ ] ConeBufferGeometry
  • [ ] CylinderBufferGeometry
  • [ ] LatheBufferGeometry
  • [ ] RingBufferGeometry
  • [ ] SphereBufferGeometry
  • [ ] TorusBufferGeometry
  • [ ] TorusKnotBufferGeometry

Materials:

  • [ ] MeshStandardMaterial

Lights:

  • [ ] DirectionalLightShadow (needed ?)
  • [ ] LightShadow (needed ?)
  • [ ] SpotLightShadow (needed ?)

Colmea avatar Sep 27 '16 22:09 Colmea

Note: I don't know if you want to support all buffer geometries ?

Well Colmea, if you're asking random strangers on the internet, then yes! Especially RingBufferGreometry.

(though hopefully I'll be able to do this myself as some stage too with the comprehensive guide at the top of the page)

davideo71 avatar Jan 22 '17 11:01 davideo71

Hello Folks,

Any updates on this ? Lots of missing ThreeJS parts as I can see. But it's a huge work.

Does the missing ThreeJS features means we can't use it ? Like Objects/Meshes/LOD for example.

Let me follow some courses on React (I come from Angular) and ThreeJS and I'll be able to shoot some PRs.

Keep things up !

3kynox avatar Feb 04 '17 18:02 3kynox

@3kynox well... it being huge work is the main problem, and to be able to have enough time and dedication to the project is also an issue, especially when it's not for money. As time passes more and more are being added but to be honest it's not as fast as I would like it to be.

I really appreciate all the attention and the issues and the pull requests, it's a bit scary but I'll try my best to at least make a part of the contribution guide so it'll be easier for everyone :)

looks at #88

toxicFork avatar Feb 04 '17 23:02 toxicFork

Thanks for answer, I understand correctly the problem because busy times is the story of my life... Too much things to do.

About my question, can we use ThreeJS not implemented features (without native components so) ?

3kynox avatar Feb 05 '17 09:02 3kynox

@toxicFork to move this issue into a GitHub project

toxicFork avatar Oct 05 '17 09:10 toxicFork