|
Posted by shmuelzon
at Jul 8, 2025, 7:33:56 PM
|
Re: Programmatically Changing Openings
The feature request for my SH3D plugin requiring this functionality was recently brought up again and I, needing some kind of win, decided to try and tackle it again.
I'm not sure everything below is required but I tried to only include things that made sense to me. I did have the basic idea of what needs to be done correct, just not the way to do it :)
The gist of it is to: Build a 3D scene with the piece of furniture and its existing dimensions from the floor plan Modify the 3D model's transformations (in my case, remove them to close the door) Calculate the bounding box of the 3D model before and after the transformation changes to get the new size and center point Update the floor plan piece with the new location and size according to the changes calculated from the step above
Here's the functional, though not that pretty, code to do that:
private void closeDoorOrWindow(HomePieceOfFurniture piece) { if (piece.getModelTransformations() == null) { return; } /* Build 3D scene with floor plan piece */ ModelManager modelManager = ModelManager.getInstance(); BranchGroup sceneTree = new BranchGroup(); TransformGroup modelTransformGroup = new TransformGroup(); BranchGroup modelRoot; sceneTree.addChild(modelTransformGroup); try { modelRoot = modelManager.loadModel(piece.getModel()); } catch (Exception ex) { return; } if (modelRoot.numChildren() == 0) return; Vector3f size = piece.getWidth() < 0 ? modelManager.getSize(modelRoot) : new Vector3f(piece.getWidth(), piece.getHeight(), piece.getDepth()); HomePieceOfFurniture modelPiece = new HomePieceOfFurniture(new CatalogPieceOfFurniture(null, null, piece.getModel(), size.x, size.z, size.y, 0, false, null, null, piece.getModelRotation(), piece.getModelFlags(), null, null, 0, 0, 1, false)); modelPiece.setX(0); modelPiece.setY(0); modelPiece.setElevation(-modelPiece.getHeight() / 2); HomePieceOfFurniture3D piece3D = new HomePieceOfFurniture3D(modelPiece, null); modelTransformGroup.addChild(piece3D); modelPiece.setModelTransformations(piece.getModelTransformations()); piece3D.update(); /* Remove transformations from 3D model and update modelPiece's size and location */ BoundingBox oldBounds = modelManager.getBounds(piece3D); Point3d oldLower = new Point3d(); oldBounds.getLower(oldLower); Point3d oldUpper = new Point3d(); oldBounds.getUpper(oldUpper); setNodeTransformations(piece3D, null); BoundingBox newBounds = modelManager.getBounds(piece3D); Point3d newLower = new Point3d(); newBounds.getLower(newLower); Point3d newUpper = new Point3d(); newBounds.getUpper(newUpper); modelPiece.setX(modelPiece.getX() + (float)(newUpper.x + newLower.x) / 2 - (float)(oldUpper.x + oldLower.x) / 2); modelPiece.setY(modelPiece.getY() + (float)(newUpper.z + newLower.z) / 2 - (float)(oldUpper.z + oldLower.z) / 2); modelPiece.setElevation(modelPiece.getElevation() + (float)(newLower.y - oldLower.y)); modelPiece.setWidth((float)(newUpper.x - newLower.x)); modelPiece.setDepth((float)(newUpper.z - newLower.z)); modelPiece.setHeight((float)(newUpper.y - newLower.y)); modelPiece.setModelTransformations(null); /* Update location and size of the floor plan piece */ float modelX = piece.isModelMirrored() ? -modelPiece.getX() : modelPiece.getX(); float modelY = modelPiece.getY(); float pieceX = (float)(piece.getX() + modelX * Math.cos(piece.getAngle()) - modelY * Math.sin(piece.getAngle())); float pieceY = (float)(piece.getY() + modelX * Math.sin(piece.getAngle()) + modelY * Math.cos(piece.getAngle())); float pieceElevation = piece.getElevation() + modelPiece.getElevation() + piece.getHeight() / 2; piece.setModelTransformations(new Transformation [0]); piece.setX(pieceX); piece.setY(pieceY); piece.setElevation(pieceElevation); piece.setWidth(modelPiece.getWidth()); piece.setDepth(modelPiece.getDepth()); piece.setHeight(modelPiece.getHeight()); }
|