private void setupEnvironments() { // カメラ設定 cam.setFrustumPerspective(80f, 1f, 1f, 1000f); cam.setLocation(new Vector3f(0, 1.5f, 10)); // cam.lookAt(new Vector3f(0, 1.6f, 0), Vector3f.UNIT_Y); flyCam.setDragToRotate(true); // ライティング DirectionalLight dl = new DirectionalLight(); dl.setColor(ColorRGBA.White.mult(3.0f)); dl.setDirection(Vector3f.UNIT_XYZ.negate()); rootNode.addLight(dl); // マテリアル設定 Material textureMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); textureMat.setTexture("ColorMap", assetManager.loadTexture("myAssets/Textures/woodFloor.jpg")); Material whitemat = assetManager.loadMaterial("Common/Materials/WhiteColor.j3m"); // 床面 Box floor = new Box(Vector3f.ZERO, 20.0f, 0.01f, 20.0f); Geometry floorGeom = new Geometry("Floor", floor); floorGeom.setMaterial(textureMat); floorGeom.setLocalTranslation(0, 0, 0); rootNode.attachChild(floorGeom); // 壁面 wallGeom[0] = new Geometry("Wall1", new Box(Vector3f.ZERO, 20f, 4f, 0.1f)); wallGeom[1] = new Geometry("Wall2", new Box(Vector3f.ZERO, 20f, 4f, 0.1f)); wallGeom[2] = new Geometry("Wall3", new Box(Vector3f.ZERO, 20f, 4f, 0.1f)); wallGeom[0].setMaterial(whitemat); wallGeom[1].setMaterial(whitemat); wallGeom[2].setMaterial(whitemat); wallGeom[0].setLocalTranslation(0, 4, -2); wallGeom[1].setLocalTranslation(-20, 4, 0); wallGeom[2].setLocalTranslation(20, 4, 0); wallGeom[1].rotate(0, (float) (Math.PI / 2f), 0); wallGeom[2].rotate(0, (float) (Math.PI / 2f), 0); rootNode.attachChild(wallGeom[0]); rootNode.attachChild(wallGeom[1]); rootNode.attachChild(wallGeom[2]); // 女性をランダムに追加 for (int i = 0; i < girl.length; i++) { girl[i] = assetManager.loadModel("myAssets/Models/WalkingGirl/WalkingGirl.obj"); girlPos[i] = new Vector3f((float) (Math.random() * 16.0f - 8f), 0, (float) (Math.random() * 8f)); // 移動スピードをランダムに girlSpeed[i] = (float) (Math.random() * -0.02f) + 0.01f; if (girlSpeed[i] < 0) { girl[i].rotate(0, (float) (-Math.PI / 2.0f), 0); } else { girl[i].rotate(0, (float) (Math.PI / 2.0f), 0); } girl[i].setLocalTranslation(girlPos[i]); this.rootNode.attachChild(girl[i]); } }
@Override public void simpleInitApp() { // sun DirectionalLight dl = new DirectionalLight(); dl.setDirection(new Vector3f(-0.1f, -1f, -1).normalizeLocal()); dl.setColor(ColorRGBA.Orange); rootNode.addLight(dl); // ambient light AmbientLight al = new AmbientLight(); al.setColor(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f)); rootNode.addLight(al); // floor Material textureMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); textureMat.setTexture("ColorMap", assetManager.loadTexture("myAssets/Textures/woodFloor.jpg")); Box floor = new Box(Vector3f.ZERO, 20.0f, 0.01f, 20.0f); Geometry floorGeom = new Geometry("Floor", floor); floorGeom.setMaterial(textureMat); rootNode.attachChild(floorGeom); // object Spatial tree = assetManager.loadModel("Models/Tree/Tree.mesh.j3o"); tree.setQueueBucket(Bucket.Transparent); rootNode.attachChild(tree); // projector PApplet applet = new ColorBarsPApplet(); PAppletProjectorNode projectorNode = new PAppletProjectorNode("projector0", assetManager, applet, 200, 200, true); rootNode.attachChild(projectorNode); rootNode.attachChild( projectorNode .getFrustmMdel()); // if you don't want to see frustum, please don't attach it to // rootNode. // projector should be added to TextureProjectorRenderer, and TextureProjectorRenderer should be // added to ViewPort. TextureProjectorRenderer ptr = new TextureProjectorRenderer(assetManager); ptr.getTextureProjectors().add(projectorNode.getProjector()); viewPort.addProcessor(ptr); // projector is a kind of Shadow, and following processes are necessary for Shadow Rendering. floorGeom.setShadowMode(ShadowMode.Receive); tree.setShadowMode(ShadowMode.CastAndReceive); // tree makes and receives shadow projectorNode.setLocalTranslation(new Vector3f(0, 10, 0)); // move the projector, projectorNode.lookAt( new Vector3f(0, 0, 0), Vector3f.UNIT_X); // and make it to look at where you want. // cam cam.setLocation(Vector3f.UNIT_XYZ.mult(10.0f)); // camera moves to 10, 10, 10 cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); // and looks at 0,0,0. }
private void scanSpatial(Spatial model) { AnimControl animControl = model.getControl(AnimControl.class); Map<Integer, List<Float>> pointsMap = null; if (weightThreshold == -1.0f) { pointsMap = RagdollUtils.buildPointMap(model); } skeleton = animControl.getSkeleton(); skeleton.resetAndUpdate(); for (int i = 0; i < skeleton.getRoots().length; i++) { Bone childBone = skeleton.getRoots()[i]; if (childBone.getParent() == null) { logger.log(Level.INFO, "Found root bone in skeleton {0}", skeleton); baseRigidBody = new PhysicsRigidBody(new BoxCollisionShape(Vector3f.UNIT_XYZ.mult(0.1f)), 1); baseRigidBody.setKinematic(mode == Mode.Kinematic); boneRecursion(model, childBone, baseRigidBody, 1, pointsMap); } } }
private static BoneWorldGrid makeBoneWorldGrid( ByteArray3d boneMeshGrid, float worldScale, MyBone bone) { Transform transform = BoneTransformUtils.boneTransform2(bone); // bounding box needed for boneMeshGrid in world grid: float bs = 1.0f; Vector3f c1 = transform.transformVector(new Vector3f(-bs, -bs, -bs), null).multLocal(worldScale); Vector3f c2 = transform.transformVector(new Vector3f(+bs, -bs, -bs), null).multLocal(worldScale); Vector3f c3 = transform.transformVector(new Vector3f(-bs, +bs, -bs), null).multLocal(worldScale); Vector3f c4 = transform.transformVector(new Vector3f(-bs, -bs, +bs), null).multLocal(worldScale); Vector3f c5 = transform.transformVector(new Vector3f(+bs, +bs, -bs), null).multLocal(worldScale); Vector3f c6 = transform.transformVector(new Vector3f(-bs, +bs, +bs), null).multLocal(worldScale); Vector3f c7 = transform.transformVector(new Vector3f(+bs, -bs, +bs), null).multLocal(worldScale); Vector3f c8 = transform.transformVector(new Vector3f(+bs, +bs, +bs), null).multLocal(worldScale); Vector3f cmin = c1.clone(); cmin.minLocal(c2); cmin.minLocal(c3); cmin.minLocal(c4); cmin.minLocal(c5); cmin.minLocal(c6); cmin.minLocal(c7); cmin.minLocal(c8); Vector3f cmax = c1.clone(); cmax.maxLocal(c2); cmax.maxLocal(c3); cmax.maxLocal(c4); cmax.maxLocal(c5); cmax.maxLocal(c6); cmax.maxLocal(c7); cmax.maxLocal(c8); int xsize = (int) FastMath.ceil(cmax.x - cmin.x); int ysize = (int) FastMath.ceil(cmax.y - cmin.y); int zsize = (int) FastMath.ceil(cmax.z - cmin.z); ByteArray3d grid = new ByteArray3d(xsize, ysize, zsize); int w = grid.getWidth(); int h = grid.getHeight(); int d = grid.getDepth(); Vector3f v = new Vector3f(); Vector3f inv = new Vector3f(); Vector3f inv2 = new Vector3f(); // we want to calculate transform: (inv - (-bs)) * (sz / (bs - (-bs))) // se let's precalculate it to (inv + shift) * scale Vector3f scale = new Vector3f(boneMeshGrid.getWidth(), boneMeshGrid.getHeight(), boneMeshGrid.getDepth()) .divideLocal(bs * 2); Vector3f shift = Vector3f.UNIT_XYZ.mult(bs); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { // calculate inverse transform at (x,y,0) and (x,y,1), the rest of the transforms in inner // loop // can be calculated by adding (inv2-inv1) because the transforms are linear v.set(x, y, 0).addLocal(cmin).divideLocal(worldScale); transform.transformInverseVector(v, inv); inv.addLocal(shift).multLocal(scale); v.set(x, y, 1).addLocal(cmin).divideLocal(worldScale); transform.transformInverseVector(v, inv2); inv2.addLocal(shift).multLocal(scale); Vector3f add = inv2.subtractLocal(inv); for (int z = 0; z < d; z++) { inv.addLocal(add); if (inv.x >= 0 && inv.x < boneMeshGrid.getWidth() && inv.y >= 0 && inv.y < boneMeshGrid.getHeight() && inv.z >= 0 && inv.z < boneMeshGrid.getDepth()) { grid.set(x, y, z, boneMeshGrid.get((int) inv.x, (int) inv.y, (int) inv.z)); } } } } // Once the boneMeshGrid has been transformed into world grid, it may suffer from // downsampling and upsampling artifacts (because the sampling is very simple nearest-neighbor). // Blurring the grid helps with both issues (blur=fake antialias). It has the added benefit // that each BoneWorldGrid will have some "smoothing buffer" around the actual shape, so that // the shape blends better with other bones' shapes. blurGrid(grid); BoneWorldGrid bwg2 = new BoneWorldGrid(); bwg2.grid = grid; bwg2.location = new Vector3i(Math.round(cmin.x), Math.round(cmin.y), Math.round(cmin.z)); return bwg2; }