UNPKG

wordpress-plugin

Version:

Boilerplate WordPress Plugin structure to support development of JavaScript frameworks: React, Vue, Vanilla, TypeScript, supporting Vite, NextJS, Nuxt, Gatsby, and JSX/TSX Components (like MUI), CSS (like Tailwind + Unity), data APIs (like REST and GraphQ

285 lines (232 loc) 8.99 kB
/* * @author mattatz / http://mattatz.github.io/ * */ /* * params * theta : the amount of randomization direction * attenuation : the attenuation rate of length * rootRange : the range of segments for branch' parent * */ THREE.TreeSpawner = function(params) { params = params || {}; this.theta = params.theta || Math.PI * 0.5; this.attenuation = params.attenuation || 0.75; this.rootRange = params.rootRange || new THREE.Vector2(0.75, 1.0); }; THREE.TreeSpawner.prototype = { spawn : function(branch, extension) { var theta = this.theta; var atten = this.attenuation; var htheta = theta * 0.5; var x = Math.random() * theta - htheta; var z = Math.random() * theta - htheta; var len = branch.length * atten; var rot = new THREE.Matrix4(); var euler = new THREE.Euler(x, 0, z); rot.makeRotationFromEuler(euler); rot.multiply(branch.rotation); var segmentIndex; extension = extension || false; if(extension) { segmentIndex = branch.segments.length - 1; } else { segmentIndex = Math.floor((Math.random() * (this.rootRange.y - this.rootRange.x) + this.rootRange.x) * branch.segments.length); } var segment = branch.segments[segmentIndex]; return new THREE.TreeBranch({ from : segment, rotation : rot, length : len, uvOffset : segment.uvOffset, uvLength : branch.uvLength, generation : branch.generation + 1, generations : branch.generations, radius : branch.radius, radiusSegments : branch.radiusSegments, heightSegments : branch.heightSegments }); } }; /* * params * from : THREE.Vector3 or TreeSegment * rotation : THREE.Matrix4 * length : Number * generation : branch' generation from root * generations : the # of generations * */ THREE.TreeBranch = function(params) { var from = params.from; this.rotation = params.rotation; this.length = params.length; this.generation = params.generation || 0; this.generations = params.generations; this.uvLength = params.uvLength || 10.0; this.uvOffset = params.uvOffset || 0.0; this.radius = params.radius || 0.1; this.radiusSegments = params.radiusSegments; this.heightSegments = params.heightSegments; if(from instanceof THREE.TreeSegment) { this.from = from; // this.position = from.position; this.position = from.position.clone().add(new THREE.Vector3(0, 1, 0).applyMatrix4(from.rotation).setLength(0.05)); } else if(from instanceof THREE.Vector3) { this.from = null; // root branch this.position = from; } else { console.warning("from argument is missing !"); } var direction = (new THREE.Vector3(0, 1, 0)).applyMatrix4(this.rotation); this.to = this.position.clone().add(direction.setLength(this.length)); this.segments = this.buildTreeSegments(this.radius, this.radiusSegments, direction, this.heightSegments); this.children = []; } THREE.TreeBranch.prototype = { buildTreeSegments : function(radius, radiusSegments, direction, heightSegments) { // randomize control point var theta = Math.PI * 0.25; var htheta = theta * 0.5; var x = Math.random() * theta - htheta; var z = Math.random() * theta - htheta; var rot = new THREE.Matrix4(); var euler = new THREE.Euler(x, 0, z); rot.makeRotationFromEuler(euler); direction.applyMatrix4(rot); var controlPoint = this.position.clone().add(direction.setLength(this.length * 0.5)); var curve = new THREE.CatmullRomCurve3([this.position, controlPoint, this.to]); var fromRatio = this.generation == 0 ? 1.0 : 1.0 - this.generation / (this.generations + 1); var toRatio = 1.0 - (this.generation + 1) / (this.generations + 1); var fromRadius = radius * fromRatio; var toRadius = radius * toRatio; var rotation = this.rotation; var segments = []; var uvLength = this.uvLength; var uvOffset = this.uvOffset; var points = curve.getPoints(heightSegments); if(this.from !== null) { uvOffset += this.from.position.distanceTo(points[0]) / uvLength; } segments.push(new THREE.TreeSegment(points[0], rotation, uvOffset, fromRadius, radiusSegments)); for(var i = 1; i < heightSegments; i++) { var p0 = points[i]; var p1 = points[i + 1]; var ry = i / (heightSegments - 1); var radius = fromRadius + (toRadius - fromRadius) * ry; var d = p1.distanceTo(p0); uvOffset += d / uvLength; var segment = new THREE.TreeSegment(p0, rotation, uvOffset, radius, radiusSegments); segments.push(segment); } return segments; }, branch : function(spawner, count) { for(var i = 0; i < count; i++) { // MEMO: // at least one child is an extended branch. this.spawn(spawner, i == 0); } this.children.forEach(function(child) { child.branch(spawner, count - 1); }); }, grow : function(spawner, count) { if(this.children.length <= 0) { this.branch(spawner, 1); } else { this.children.forEach(function(child) { child.grow(spawner); }); } }, spawn : function(spawner, extension) { var child = spawner.spawn(this, extension); this.children.push(child); }, branchlets : function() { if(this.children.length == 0) { return this; } else { return Array.prototype.concat.apply( [], this.children.map(function(child) { return child.branchlets(); }) ); } }, calculateLength : function() { var segments = this.segments; var length = 0; for(var i = 0, n = segments.length - 1; i < n; i++) { var p0 = segments[i].position; var p1 = segments[i + 1].position; length += p0.distanceTo(p1); } return length; } }; /* * position : THREE.Vector3 * rotation : THREE.Matrix4 * */ THREE.TreeSegment = function(position, rotation, uvOffset, radius, radiusSegments) { this.position = position; this.rotation = rotation; this.uvOffset = uvOffset; this.radius = radius; this.vertices = []; this.uvs = []; this.build(radius, radiusSegments); } THREE.TreeSegment.prototype = { build : function(radius, radiusSegments) { var thetaLength = Math.PI * 2; for(var x = 0; x <= radiusSegments; x++) { var u = x / radiusSegments; var vertex = new THREE.Vector3(radius * Math.sin(u * thetaLength), 0, radius * Math.cos(u * thetaLength)).applyMatrix4(this.rotation).add(this.position); this.vertices.push(vertex); this.uvs.push(new THREE.Vector2(u, this.uvOffset)); } } }; THREE.Tree = function(params, spawner) { params = params || {}; var from = params.from || new THREE.Vector3(); var rotation = new THREE.Matrix4(); if(params.rotation) { if(params.rotation instanceof THREE.Euler) { var euler = params.rotation; rotation.makeRotationFromEuler(euler); } else if(params.rotation instanceof THREE.Matrix4) { rotation = params.rotation; } } var length = params.length || 3.0; var uvLength = params.uvLength || 10.0; var generations = (params.generations !== undefined) ? params.generations : 5; var radius = params.radius || 0.1; this.radiusSegments = params.radiusSegments || 8; this.heightSegments = params.heightSegments || 8; this.generations = generations; this.root = new THREE.TreeBranch({ from : from, rotation : rotation, length : length, uvLength : uvLength, generation : 0, generations : this.generations, radius : radius, radiusSegments : this.radiusSegments, heightSegments : this.heightSegments }); this.spawner = spawner || new THREE.TreeSpawner(); this.root.branch(this.spawner, this.generations); } THREE.Tree.prototype = { grow : function(count, spawner) { spawner = spawner || this.spawner; this.generation++; this.root.grow(spawner, count); }, branchlets : function() { return this.root.branchlets(); } };