I’ve been trying to wrap an imported object (Collada file) around a cylinder in threejs, regardless of what the size of the imported object is, I’ve tried CurveModifier, and that doesn’t seem to work for a full 360-degree wrap. End result
This image is from blender, but basically this is what I am looking for, I’ve tried the code below, it plots the object in a circle, but I have 2 issues
- I can’t get the size and position to match the cylinder
- when I export the file, the modifiers are lost.
var width = $('#col_canvas').width();
var height = $('#col_canvas').height();
var fov = 45;
var aspect = width / height;
var near = 0.001;
var far = 100000;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var mouseX = 0;
var mouseY = 0;
var SELECTED;
var windowHalfX = width / 2;
var windowHalfY = height / 2;
var theta = 0;
var antialias = true;
var alpha = true;
var canvas = $("#canvas")[0];
var camera_init_pos = [0, 30, 0];
var camera_init_lookAt = [0, 0, 0];
var renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: antialias,
alpha: alpha
});
renderer.setSize(width, height);
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(camera_init_pos[0], camera_init_pos[1], camera_init_pos[2]);
camera.lookAt(camera_init_lookAt[0], camera_init_lookAt[1], camera_init_lookAt[2]);
var scene = new THREE.Scene();
var orbitControls = new THREE.OrbitControls(camera, renderer.domElement);
orbitControls.update();
orbitControls.addEventListener('change', render);
loadLights();
function animate() {
requestAnimationFrame(animate);
orbitControls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', resize);
function resize() {
camera.left = camera.bottom * aspect;
camera.right = camera.top * aspect;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
render();
}
//*****************************************************************************************
var object_names = [];
var geo_cylinder, geo_cutbox, geo_wrapper, geo_text;
var mesh_cylinder, mesh_cutbox, mesh_wrapper, mesh_text;
var url_wrapper, url_text;
var filetype_wrapper, filetype_text;
var radius, height, segments, cutbox_x, cutbox_y, cutbox_z;
$('#btn_create_new').click(function() {
radius = parseFloat($('#txt_modal_cyl_radius').val());
height = parseFloat($('#txt_modal_cyl_height').val());
segments = parseFloat($('#txt_modal_cyl_segments').val());
cutbox_x = parseFloat($('#txt_modal_cutbox_x').val());
cutbox_y = parseFloat($('#txt_modal_cutbox_y').val());
cutbox_z = parseFloat($('#txt_modal_cutbox_z').val());
geo_cylinder = new THREE.CylinderGeometry(radius / 2, radius / 2, height, segments);
geo_cylinder.rotateX(getAngle(90));
object_names.push(geo_cylinder.name);
mesh_cylinder = new THREE.Mesh(geo_cylinder, silver_material);
mesh_cylinder.name = 'Cylinder';
scene.add(mesh_cylinder);
var cylinder_size = new THREE.Box3().setFromObject(mesh_cylinder)
geo_cutbox = new THREE.BoxGeometry(cutbox_x, cutbox_y, cutbox_z);
geo_cutbox.translate(0, cutbox_x * 1.114286, 0);
object_names.push(geo_cutbox.name);
mesh_cutbox = new THREE.Mesh(geo_cutbox, silver_material);
mesh_cutbox.name = 'CutBox';
scene.add(mesh_cutbox);
loadDAEFile(url_wrapper, filetype_wrapper);
});
function loadDAEFile(url) {
var geo_cir = new THREE.CircleGeometry(radius, 132);
// geo_cir.rotateX(getAngle(-90));
var points_cir = [];
$.each(geo_cir.vertices, function(i, v) {
if (i > 0) {
points_cir.push(v);
}
});
colladaLoader.load(url, function(dae) {
dae.scene.traverse(function(child) {
if (child.type == 'Mesh') {
mesh_wrapper = child;
}
});
geo_wrapper = mesh_wrapper.geometry;
mesh_wrapper.name = 'Wrapper';
var wrapper_size = new THREE.Box3().setFromObject(mesh_wrapper);
let size = wrapper_size.getSize(new THREE.Vector3());
var max_side = Math.max(size.x, size.y, size.z)
var scale = height / max_side;
console.log(geo_wrapper);
geo_wrapper.scale(scale, scale, scale);
var box = new THREE.Box3().setFromObject(mesh_wrapper);
var center = new THREE.Vector3();
var box_center = box.getCenter(center);
mesh_wrapper.position.set(box_center.x * -1, box_center.y * -1, box_center.z * -1); // center the model
// scene.add(mesh_wrapper);
curveThis(mesh_wrapper, radius, points_cir);
})
}
$("#file_wrapper").change(function(e) {
file = $(this).get(0).files[0];
url_wrapper = URL.createObjectURL(file);
var filename = file.name;
var extension = filename.split('.').pop();
filetype_wrapper = extension;
$('#sel_filetype_wrapper').val(extension);
});
$("#file_text").change(function(e) {
file = $(this).get(0).files[0];
url_text = URL.createObjectURL(file);
var filename = file.name;
var extension = filename.split('.').pop();
filetype_text = extension;
$('#sel_filetype_text').val(extension);
});
function curveThis(dae, circle_radius, points_cir) {
var boundingBox = new THREE.Box3().setFromObject(dae);
var circle_arc_length = ((3.6 * (circle_radius - (circle_radius / 20))) * Math.PI);
var size = boundingBox.getSize();
var scale_to_radius = (circle_arc_length / size.x) / 100;
var scaleX = size.x * scale_to_radius * 2.5;
var scaleY = circle_radius / size.y * 2.5;
var scaleZ = circle_radius / size.z * 2.5;
geometry = dae.geometry;
geometry.scale(scaleX, scaleY, 1);
var material = new THREE.MeshStandardMaterial({
color: 0xff0000,
side: THREE.DoubleSide
});
var cube = new THREE.Mesh(geometry, material);
var curveHandles = [];
var boxGeometry = new THREE.BoxGeometry(0.1, 0.1, 0.1);
var boxMaterial = new THREE.MeshBasicMaterial();
var curves = [
points_cir
].map(function(curvePoints) {
var curveVertices = curvePoints.map(function(handlePos) {
var handle = new THREE.Mesh(boxGeometry, boxMaterial);
handle.position.copy(handlePos);
curveHandles.push(handle);
scene.add(handle);
return handle.position;
});
var curve = new THREE.CatmullRomCurve3(curveVertices);
curve.curveType = 'centripetal';
curve.closed = true;
var points = curve.getPoints(50);
var line = new THREE.LineLoop(
new THREE.BufferGeometry().setFromPoints(points),
new THREE.LineBasicMaterial({
color: 0x00ff00
})
);
scene.add(line);
return {
curve,
line
};
});
var numberOfInstances = 1;
flow = new THREE.InstancedFlow(numberOfInstances, curves.length, geometry, material);
curves.forEach(function({
curve
}, i) {
flow.updateCurve(i, curve);
scene.add(flow.object3D);
});
for (let i = 0; i < numberOfInstances; i++) {
var curveIndex = i % curves.length;
flow.setCurve(i, curveIndex);
flow.moveIndividualAlongCurve(i, i * 1 / numberOfInstances);
flow.object3D.setColorAt(i, new THREE.Color(0xffffff * Math.random()));
}
}