简体   繁体   English

如何使用Aframe js创建平行四边形?

[英]How to create parallelogram using Aframe js?

I have been trying to create a parallelogram using Aframe js but i couldn't find primitive to create. 我一直在尝试使用Aframe js创建平行四边形,但找不到原始图。 Please help me to create it. 请帮助我创建它。

You could make it manually, by creating a custom component , which will create a mesh based on a custom THREE.js shape: 您可以通过创建自定义组件手动进行创建,该组件将基于自定义THREE.js形状创建网格:

let points = [];
points.push(new THREE.Vector2(0, 0));
points.push(new THREE.Vector2(3, 0));
points.push(new THREE.Vector2(5, 3));
points.push(new THREE.Vector2(2, 3));

for (var i = 0; i < points.length; i++) {
  points[i].multiplyScalar(0.25);
}
var shape = new THREE.Shape(points);
var material = new THREE.MeshBasicMaterial({
  color: 0x00ff00
});
var mesh = new THREE.Mesh(geometry, material);
this.el.object3D.add(mesh);

working fiddle here . 这里工作。 Please check out this question as well. 请也检查这个问题

Here is how I would create any custom shape that I wanted (using parallelogram as example), although Piotr's answer is much more succinct, maybe another approach will be helpful. 这是我将如何创建所需的任何自定义形状的方法(以平行四边形为例),尽管Piotr的回答更为简洁,也许另一种方法会有所帮助。

First create a custom component that contains all the vertices you need for your shape. 首先创建一个自定义组件,其中包含形状所需的所有顶点。 (Sorry that vertices makes it long but its clearer whats going on) (对不起,顶点会使它变长,但发生了什么事情却更加清晰)

//register parallelogram component

AFRAME.registerComponent('parallelogram', {

//create schema
schema: {    
},

//define vertices of a parallelogram
//made up of 4 triangles that are combined together
para_vertices: [
    //first triangle
    {
        'x': -1,
        'y': 0,
        'z': 0,
    },
    {
        'x': 0,
        'y': 0,
        'z': 0,
    },
    {
        'x': 0,
        'y': 1,
        'z': 0,
    },
    //second triangle
    {
        'x': 0,
        'y': 0,
        'z': 0,
    },
    {
        'x': 1,
        'y': 0,
        'z': 0,
    },
    {
        'x': 0,
        'y': 1,
        'z': 0,
    }, 
    //third triangle  
    {
        'x': 1,
        'y': 0,
        'z': 0,
    },
    {
        'x': 1,
        'y': 1,
        'z': 0,
    },
    {
        'x': 0,
        'y': 1,
        'z': 0,
    },
    //fourth triangle  
    {
        'x': 1,
        'y': 0,
        'z': 0,
    },
    {
        'x': 2,
        'y': 1,
        'z': 0,
    },
    {
        'x': 1,
        'y': 1,
        'z': 0,
    }, 

],


init: function (){

    //create 3.js geometry      
    this.geometry = new THREE.Geometry();
    var geometry = this.geometry

    //get the vertices that we described above
    var verts = this.para_vertices
    //calculate number of faces     
    var faceCount = verts.length/3

    //loop through vertices and add to the geometry
    for (var i = 0; i < verts.length; i++) {
        var v3 = verts[i]
        geometry.vertices.push ( new THREE.Vector3(v3.x, v3.y, v3.z) );
    }
    //add faces to geometry 
    for (var i = 0; i < faceCount; i++) {
        a = i+i*2
        geometry.faces.push(new THREE.Face3(a, a+1, a+2))
    }
    geometry.computeBoundingBox();
    geometry.computeFaceNormals();
    geometry.computeVertexNormals();
    geometry.mergeVertices();

    //use out of the box material that you add to the entity in the primitive below
    this.material = this.el.components.material.material
    //make a new 3.js mesh combining the geometry and the material
    this.mesh = new THREE.Mesh(this.geometry, this.material);
    //add this mesh to our parent element
    this.el.setObject3D('mesh', this.mesh);

},

});

Then, make a primitive by using that component and the existing material component 然后,使用该组件和现有的材质组件制作基本体

//make it a primitive by defining a-parallelogram and adding the above component
AFRAME.registerPrimitive('a-parallelogram', {
  defaultComponents: {
    //add the material component
    // you could define this yourself in the above component if you prefer
    material: {},
    //add the parallelogram component we have just created
    parallelogram: {},
  },
  mappings: { 
    //specify any attributes and their mappings that you would like to be able to define from the html layer
    color: 'material.color',
  }, 
});

And you can then use that in your HTML like so 然后您可以像这样在HTML中使用它

<html>
  <head>
    <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
    <!-- include a script that contains the parallelogram component -->
    <script src="scripts/parallelogram.js"></script>
  </head>
  <body>
    <a-scene>
        <a-parallelogram position="-1 0.5 -5" color="blue"></a-parallelogram>
        <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
        <a-sky color="#ECECEC"></a-sky>
    </a-scene>
  </body>
</html>

Here is a working fiddle 是一个工作的小提琴

I hope that's helpful, you can find more on creating custom components here and in particular for making shapes here 希望对您有所帮助,您可以在此处找到有关创建自定义组件的更多信息,尤其是在此处可以制作形状

Alternatively, here is another approach that separates the 'shapemaker' from the 'shapedata' so you can just have one script for making whatever custom shape you like and add in the shape-specific data by registering a custom primitive (that uses that component) and passing the shape-specific information from there. 另外,这是将“ shapemaker”“ shapeata”分开的另一种方法,因此您只需要一个脚本即可制作所需的任何自定义形状,并通过注册自定义基元(使用该组件)来添加形状特定的数据并从那里传递形状特定的信息。

So, a generic shapemaker component (will parse the vertices in the schema when passed from the primitive registration) 因此,一个通用的shapemaker组件(从原始注册传递过来时,将解析架构中的顶点)

//register custom shape maker component
AFRAME.registerComponent('customshape', {

    schema: {
        model: {
            default: {},
            parse : function (value){  
                return value
            }
        },   
    },    

    init: function (){

        this.geometry = new THREE.Geometry();
        var geometry = this.geometry
        var verts = this.data.model
        var faceCount = verts.length/3
        for (var i = 0; i < verts.length; i++) {
            var v3 = verts[i]
            geometry.vertices.push(new THREE.Vector3(v3.x, v3.y, v3.z));
        }       
        for (var i = 0; i < faceCount; i++) {
            a = i*3
            geometry.faces.push(new THREE.Face3(a, a+1, a+2))
        }
        geometry.computeBoundingBox();
        geometry.computeFaceNormals();
        geometry.computeVertexNormals();
        geometry.mergeVertices();   
        this.material = this.el.components.material.material
        this.mesh = new THREE.Mesh(this.geometry, this.material);
        this.el.setObject3D('mesh', this.mesh);

    },

});

Then register whatever shape you want as a primitive (eg parallelogram) and pass in the vertices as a value when you assign the default components 然后将任何想要的形状注册为基本形状(例如,平行四边形),并在分配默认组件时将顶点作为值传递

//register particular shape primitive and pass in shape specific vertices
AFRAME.registerPrimitive('a-parallelogram', {
  defaultComponents: {
    material: {},
    customshape: {model: [
        {
            'x': -1,
            'y': 0,
            'z': 0,
        },
        {
            'x': 0,
            'y': 0,
            'z': 0,
        },
        {
            'x': 0,
            'y': 1,
            'z': 0,
        },
        {
            'x': 0,
            'y': 0,
            'z': 0,
        },
        {
            'x': 1,
            'y': 0,
            'z': 0,
        },
        {
            'x': 0,
            'y': 1,
            'z': 0,
        }, 
        {
            'x': 1,
            'y': 0,
            'z': 0,
        },
        {
            'x': 1,
            'y': 1,
            'z': 0,
        },
        {
            'x': 0,
            'y': 1,
            'z': 0,
        },
        {
            'x': 1,
            'y': 0,
            'z': 0,
        },
        {
            'x': 2,
            'y': 1,
            'z': 0,
        },
        {
            'x': 1,
            'y': 1,
            'z': 0,
        }, 

    ],
},
  },
  mappings: { 
    color: 'material.color',
  }, 
});

And then use that in the HTML 然后在HTML中使用

<html>
  <head>
    <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
    <script src="scripts/simplecustomshapemaker.js"></script>
  </head>
  <body>
    <a-scene>
        <a-parallelogram position="-1 0.5 -5" color="blue"></a-parallelogram>
        <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
        <a-sky color="#ECECEC"></a-sky>
    </a-scene>
  </body>
</html>

So by using that same custom shapemaker script I could define a number of shapes as primitives without having to change that script. 因此,通过使用相同的自定义shapemaker脚本,我可以将许多形状定义为基本体,而不必更改该脚本。

Here is a working fiddle 是一个工作的小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM