I want to be able to deform the shape of the wig by putting a mesh on the wig image.
In the current source code, the shape of the wig is transformed into a straight line and appears in a pointed form.
How can I make the image shape move a little more round?
<html>
<head>
<meta charset=utf-8>
<title>My first Three.js app</title>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<canvas width=750; height=900;></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.js"></script>
<script>
var ARC_SEGMENTS = 200;
var scene = new THREE.Scene();
// var camera = new THREE.PerspectiveCamera(50, 1, 1, 1000);
var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 10, 0);
// camera.position.z = 400;
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
canvas: document.querySelector("canvas"),
antialias: true,
alpha: true
});
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.PlaneBufferGeometry(10, 10, 15, 15);
geometry.rotateX(-Math.PI * 0.5);
// const texture = new THREE.TextureLoader().load('https://img.lovepik.com/free-png/20220126/lovepik-short-wig-png-image_401770231_wh1200.png');
const texture = new THREE.TextureLoader().load('images/hairstyle.png');
var img = new THREE.MeshBasicMaterial({ //CHANGED to MeshBasicMaterial
map: texture
});
img.map.needsUpdate = true; //ADDED
// for(let i=0; i<geometry.vertices.length/2; i++) {
// geometry.vertices[2*i].z = Math.pow(2, i/20);
// geometry.vertices[2*i+1].z = Math.pow(2, i/20);
// }
//
var plane = new THREE.Mesh(geometry, img);
// plane.doubleSided = true;
// plane.rotation.y = Math.PI/2-0.5;
scene.add(plane);
var splines = {};
var points = new THREE.Points(geometry, new THREE.PointsMaterial({
color : 0xffffff,
map: "0xffffff"
}));
scene.add(points);
var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = 0.25;
var mouse = new THREE.Vector2();
var intersects = null;
var plane = new THREE.Plane();
var planeNormal = new THREE.Vector3();
var currentIndex = null;
var planePoint = new THREE.Vector3();
var dragging = false;
window.addEventListener("mousedown", mouseDown, false);
window.addEventListener("mousemove", mouseMove, false);
window.addEventListener("mouseup", mouseUp, false);
window.addEventListener("touchstart", touchStart, false);
window.addEventListener("touchmove", touchMove, false);
window.addEventListener("touchend", touchEnd, false);
window.addEventListener("touchcancel", touchCancel, false);
function touchStart(event) {
console.log("");
console.log("[main] : [handleStart] : [start]");
BodyScrollDisAble();
setRaycaster(event);
getIndex();
dragging = true;
var startId = event.targetTouches[0].target.id;
console.log("[main] : [handleStart] : [ID] : " + startId);
}
function touchMove(event) {
console.log("");
console.log("[main] : [handleMove] : [start]");
BodyScrollDisAble();
var moveId = event.targetTouches[0].target.id;
console.log("[main] : [handleMove] : [ID] : " + moveId);
var moveX = event.changedTouches[0].clientX;
var moveY = event.changedTouches[0].clientY;
console.log("[main] : [handleMove] : [X] : " + moveX);
console.log("[main] : [handleMove] : [Y] : " + moveY);
console.log("");
if (dragging && currentIndex !== null) {
console.log("[dragging] : [currentIndex] : [Y] : ");
setRaycaster(event);
raycaster.ray.intersectPlane(plane, planePoint);
geometry.attributes.position.setXY(currentIndex, planePoint.x, planePoint.y);
geometry.attributes.position.needsUpdate = true;
}
}
function touchEnd(event) {
console.log("");
console.log("[main] : [handleEnd] : [end]");
BodyScrollAble();
event.preventDefault();
dragging = false;
currentIndex = null;
var endX = event.changedTouches[0].clientX;
var endY = event.changedTouches[0].clientY;
console.log("[main] : [handleEnd] : [X] : " + endX);
console.log("[main] : [handleEnd] : [Y] : " + endY);
console.log("");
}
function touchCancel(event) {
console.log("");
console.log("[main] : [handleEnd] : [end]");
BodyScrollAble();
dragging = false;
currentIndex = null;
var endX = event.changedTouches[0].clientX;
var endY = event.changedTouches[0].clientY;
console.log("[main] : [handleEnd] : [X] : " + endX);
console.log("[main] : [handleEnd] : [Y] : " + endY);
console.log("");
}
function BodyScrollDisAble(){
document.body.style.overflow = "hidden";
}
function BodyScrollAble(){
document.body.style.overflow = "auto";
}
function mouseDown(event) {
setRaycaster(event);
getIndex();
dragging = true;
}
function mouseMove(event) {
if (dragging && currentIndex !== null) {
setRaycaster(event);
raycaster.ray.intersectPlane(plane, planePoint);
// geometry.attributes.position.setXYZ(currentIndex, planePoint.x, planePoint.y, planePoint.z);
geometry.attributes.position.setXYZ(currentIndex, planePoint.x, planePoint.y, planePoint.z);
// geometry.attributes.position.setXYZ(currentIndex+10, planePoint.x, planePoint.y, planePoint.z);
// geometry.attributes.position.setXYZ(currentIndex-1, planePoint.x, planePoint.y, planePoint.z);
// geometry.attributes.position.setXYZ(currentIndex+10, planePoint.x, planePoint.y, planePoint.z);
// geometry.attributes.position.setXYZ(currentIndex-1, planePoint.x, planePoint.y, planePoint.z);
console.log("currentIndex : " + currentIndex);
console.log("planePoint.x : " + planePoint.x);
console.log("planePoint.y : " + planePoint.y);
console.log("planePoint.z : " + planePoint.z);
geometry.attributes.position.needsUpdate = true;
}
}
function mouseUp(event) {
dragging = false;
currentIndex = null;
}
function getIndex() {
intersects = raycaster.intersectObject(points);
if (intersects.length === 0) {
currentIndex = null;
return;
}
currentIndex = intersects[0].index;
setPlane(intersects[0].point);
}
function setPlane(point) {
planeNormal.subVectors(camera.position, point).normalize();
plane.setFromNormalAndCoplanarPoint(planeNormal, point);
}
function setRaycaster(event) {
getMouse(event);
raycaster.setFromCamera(mouse, camera);
}
function getMouse(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function resizeCanvasToDisplaySize() {
// you must pass false here or three.js sadly fights the browser
renderer.setSize(window.innerWidth, window.innerHeight, false);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
// set render target sizes here
}
const resizeObserver = new ResizeObserver(resizeCanvasToDisplaySize);
resizeObserver.observe(renderer.domElement, {
box: 'content-box'
});
</script>
</body>