I have been trying to create a parallelogram using Aframe js but i couldn't find primitive to create. 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:
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.
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>
<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.
So, a generic shapemaker component (will parse the vertices in the schema when passed from the primitive registration)
//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>
<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.
Here is a working fiddle
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.