Hello,
I am trying to make some 3d playing cards in the browser. I have generated a rounded-rectangle shape by using ExtrudeGeometry with some lines I’ve drawn. I’m having three issues:
- The Image texture isn’t applying to the full shape.
- I cant specify an image for the back of the extruded texture.
- The shadows are catching on the rounded corner pieces:
function createCardGeometry( width, depth, height, radius) {
let shape = new THREE.Shape();
shape.moveTo(0, width-radius)
shape.lineTo(0, width-radius)
shape.absarc(radius, width-radius, radius, 0, Math.PI/2, true)
shape.lineTo(height-radius, width)
shape.absarc(height-radius, width-radius, radius, 3*Math.PI/2, 2*Math.PI, true);
shape.lineTo(height,radius)
shape.absarc(height-radius, radius, radius, Math.PI/2, 3*Math.PI/2,true)
shape.lineTo(radius, 0)
shape.absarc(radius, radius, radius, 0, Math.PI, true)
const extrudeSettings = {
steps: 16,
depth: depth,
bevelEnabled: false
}
let card_shape = new THREE.ExtrudeGeometry( shape, extrudeSettings )
card_shape.lookAt(new THREE.Vector3(0,1,0))
return card_shape;
}
The absarc sections were done almost entirely through trial and error. It’s pretty likely those are causing the shading issue
I call that as follows:
function createCard(x,y,z,rotation,image){
let pos = {x: x, y: y, z: z};
let scale = {width: 6.91, depth: 0.1, height: 10.56};
let quat = {x: 0, y: 0, z: 0, w: 1};
let mass = 1;
//threeJS Section
let texture = new THREE.TextureLoader().load( `../../card_images/${image}.png` );
texture.anisotropy = 16;
let texture_back = new THREE.TextureLoader().load( `../../card_images/card_back.png` );
texture_back.anisotropy = 16;
var cardMaterialArray = [];
cardMaterialArray.push(new THREE.MeshStandardMaterial({map: texture}))
// cardMaterialArray.push(new THREE.MeshPhongMaterial({map: texture_back, color: 0xffffff}))
var cardTextures = new THREE.MeshStandardMaterial({map: texture})
let cardGeometry = createCardGeometry(scale.height, scale.depth, scale.width, 0.5)
let card = new THREE.Mesh(cardGeometry, cardTextures);
card.castShadow = true;
card.receiveShadow = true;
scene.add(card);
//Ammojs Section
let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
let quaternion = new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w )
quaternion.setEulerZYX(0,0,0)
transform.setRotation(quaternion);
let motionState = new Ammo.btDefaultMotionState( transform );
let colShape = new Ammo.btBoxShape( new Ammo.btVector3( scale.width * 0.5, scale.depth * 0.5, scale.height * 0.5 ) );
colShape.setMargin( 0.05 );
let localInertia = new Ammo.btVector3( 0, 0, 0 );
colShape.calculateLocalInertia( mass, localInertia );
let rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, colShape, localInertia );
let body = new Ammo.btRigidBody( rbInfo );
physicsWorld.addRigidBody(body);
card.userData.physicsBody = body;
rigidBodies.push(card);
}
I’m pretty sure Ammo handles the positioning in the world as well as the physics.
I’ve googled a lot and found some things about about UV mapping, but every example I’ve found I don’t really understand.
If there’s an easier way of going about this instead of extruding Geometry i’d like to hear it, though I dont see why I shouldn’t be able to get this to work.