Commit 8176593d authored by Andrey Filippov's avatar Andrey Filippov

Refactored to have multiple world (needed when scenes can not be

matched)
parent 7e53b24d
...@@ -25,11 +25,11 @@ ...@@ -25,11 +25,11 @@
package com.elphel.imagej.tileprocessor.lwoc; package com.elphel.imagej.tileprocessor.lwoc;
import java.io.Serializable; import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger; ///import java.util.concurrent.atomic.AtomicInteger;
public class LwocMesh implements Serializable { public class LwocMesh implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
static AtomicInteger MESH_ID = new AtomicInteger(); /// static AtomicInteger MESH_ID = new AtomicInteger();
// static ArrayList<LwocMesh> LWOC_MESHES; // static ArrayList<LwocMesh> LWOC_MESHES;
int id; // assign unique ID int id; // assign unique ID
String stimestamp; // mesh is always referenced to a single scene String stimestamp; // mesh is always referenced to a single scene
...@@ -37,7 +37,7 @@ public class LwocMesh implements Serializable { ...@@ -37,7 +37,7 @@ public class LwocMesh implements Serializable {
double [] hdims_xyz; // world bounding box half-dimensions along x,y,z double [] hdims_xyz; // world bounding box half-dimensions along x,y,z
public static void resetMeshes() { public static void resetMeshes() {
MESH_ID.set(0); /// MESH_ID.set(0);
// LWOC_MESHES = new ArrayList<LwocMesh>(); // LWOC_MESHES = new ArrayList<LwocMesh>();
} }
// maybe use mesh properties instead of id? // maybe use mesh properties instead of id?
...@@ -48,7 +48,7 @@ public class LwocMesh implements Serializable { ...@@ -48,7 +48,7 @@ public class LwocMesh implements Serializable {
String stimestamp String stimestamp
) { ) {
this.stimestamp = stimestamp; this.stimestamp = stimestamp;
id = MESH_ID.getAndIncrement(); /// id = MESH_ID.getAndIncrement();
// LWOC_MESHES.add(this); // LWOC_MESHES.add(this);
} }
......
...@@ -24,11 +24,11 @@ ...@@ -24,11 +24,11 @@
package com.elphel.imagej.tileprocessor.lwoc; package com.elphel.imagej.tileprocessor.lwoc;
import java.io.FileInputStream; //import java.io.FileInputStream;
import java.io.FileOutputStream; //import java.io.FileOutputStream;
import java.io.IOException; //import java.io.IOException;
import java.io.ObjectInputStream; //import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; //import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -37,99 +37,21 @@ import com.elphel.imagej.common.MultiThreading; ...@@ -37,99 +37,21 @@ import com.elphel.imagej.common.MultiThreading;
public class LwocOctree implements Serializable { public class LwocOctree implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final int NUM_CHILDREN = 8; public static final int NUM_CHILDREN = 8;
public static double MIN_HSIZE = 0.3; // meter - do not subdivide more // static AtomicInteger OCTREE_ID = new AtomicInteger();
// can not be used as intersecting meshes' bb will not decrease number after splitting
public static int MAX_MESH_CENTERS = 10; // maximal number of meshes in a leaf;
public static int MAX_CAMERAS = 10; // maximal number of cameras in a leaf;
public static LwocOctree lwoc_root = null;
// static ArrayList<LwocOctree> LWOK_OCTREE = new ArrayList<LwocOctree>();
static AtomicInteger OCTREE_ID = new AtomicInteger();
static List<LwocScene> pendingScenes; // synchronized - add not-yet-added scenes pending growing world static List<LwocScene> pendingScenes; // synchronized - add not-yet-added scenes pending growing world
static List<LwocMesh> pendingMeshes; // synchronized - add not-yet-added meshes pending growing world static List<LwocMesh> pendingMeshes; // synchronized - add not-yet-added meshes pending growing world
static List<LwocOctree> pendingLeafNodes;// synchronized - leaf nodes needed to be split static List<LwocOctree> pendingLeafNodes;// synchronized - leaf nodes needed to be split
// static List<LwocWorld> lwoc_worlds; //
int id; // assign unique ID int id; // assign unique ID
LwocOctree parent; transient LwocWorld world;
transient LwocOctree parent;
LwocOctree [] children; LwocOctree [] children;
LwocLeaf leaf; // LwocLeaf leaf; //
double [] center; // x-center, y-center, z-center double [] center; // x-center, y-center, z-center
double hsize; double hsize;
/**
* Serialize and write world to an output stream
* @param oos ObjectOutputStream to write to.
* @throws IOException
*/
private void writeObject(ObjectOutputStream oos)
throws IOException {
oos.defaultWriteObject();
if (parent == null) { // write static members
oos.writeObject(MIN_HSIZE);
oos.writeObject(MAX_MESH_CENTERS);
oos.writeObject(MAX_CAMERAS);
oos.writeObject(OCTREE_ID.get());
oos.writeObject(LwocMesh.MESH_ID.get());
}
}
/**
* Read input stream and deserialize it to world octree structure.
* @param ois ObjectInputStream to read from
* @throws ClassNotFoundException
* @throws IOException
*/
private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
ois.defaultReadObject();
if (parent == null) { // read static members
MIN_HSIZE = (Double) ois.readObject();
MAX_MESH_CENTERS = (Integer) ois.readObject();
MAX_CAMERAS = (Integer) ois.readObject();
OCTREE_ID.set( (Integer) ois.readObject());
LwocMesh.MESH_ID.set((Integer) ois.readObject());
}
}
/**
*
* @param path
*/
public static void saveWorld(String path) {
try {
FileOutputStream fileOut = new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(lwoc_root); // will cause all world to be saved
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in "+path);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void restoreWorld(String path) {
try {
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
lwoc_root = (LwocOctree) in.readObject();
in.close();
fileIn.close();
} catch (IOException e) {
e.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println(path+" not found");
c.printStackTrace();
return;
}
}
public static void addPendingScene(LwocScene scene) { public static void addPendingScene(LwocScene scene) {
synchronized(pendingScenes) { synchronized(pendingScenes) {
pendingScenes.add(scene); pendingScenes.add(scene);
...@@ -148,22 +70,6 @@ public class LwocOctree implements Serializable { ...@@ -148,22 +70,6 @@ public class LwocOctree implements Serializable {
} }
} }
/**
* Initialize Octree data and set initial world node. It is possible to grow
* world as needed later.
* @param center world center: x,y,z in meters. Usually {0,0,0}
* @param world_hsize Half linear dimension of the world
*/
public static void initOctree(double [] center, double world_hsize) {
LwocMesh.resetMeshes();
LwocScene.resetScenes();
resetPending();
// LWOK_OCTREE = new ArrayList<LwocOctree>();
// Add a single leaf node
lwoc_root = new LwocOctree(null, center, world_hsize);
lwoc_root.leaf = new LwocLeaf();
}
/** /**
* Synchronized lists of pending scenes, meshes and nodes are used to delay modification of * Synchronized lists of pending scenes, meshes and nodes are used to delay modification of
* the world octree and its elements from the multithreaded environment. These lists should * the world octree and its elements from the multithreaded environment. These lists should
...@@ -202,18 +108,19 @@ public class LwocOctree implements Serializable { ...@@ -202,18 +108,19 @@ public class LwocOctree implements Serializable {
/** /**
* LwocOctree constructor * LwocOctree constructor
* @param lwocWorld World global parameters
* @param parent Parent node * @param parent Parent node
* @param xyz position of the node center in meters * @param xyz Position of the node center in meters
* @param hsize Node half size - each of the X,Y,Z coordinates of the internal * @param hsize Node half size - each of the X,Y,Z coordinates of the internal
* points are limited within +/-hsize from the node center * points are limited within +/-hsize from the node center
*/ */
public LwocOctree (LwocOctree parent, public LwocOctree (
LwocWorld lwocWorld,
LwocOctree parent,
double [] xyz, double [] xyz,
double hsize) { double hsize) {
id = OCTREE_ID.getAndIncrement();
this.parent = parent; this.parent = parent;
this.hsize = hsize; this.hsize = hsize;
// LWOK_OCTREE.add(this);
} }
/** /**
...@@ -222,14 +129,15 @@ public class LwocOctree implements Serializable { ...@@ -222,14 +129,15 @@ public class LwocOctree implements Serializable {
* @return Octree node that includes the point or null if the point * @return Octree node that includes the point or null if the point
* is outside the root node (the whole world) * is outside the root node (the whole world)
*/ */
public static LwocOctree getLeafNode( // if null - needs growing world //FIXME: obey border (on the edges of max hsize of the root) nodes
public LwocOctree getLeafNode( // if null - needs growing world
double [] xyz) { // thread safe double [] xyz) { // thread safe
if (!lwoc_root.contains(xyz)) return null; // needs growing world if (!world.getLwocRoot().contains(xyz)) return null; // needs growing world
LwocOctree node = lwoc_root; LwocOctree node = world.getLwocRoot();
while (lwoc_root.children != null) { while (world.getLwocRoot().children != null) {
int indx = 0; int indx = 0;
for (int dm = 0; dm < 3; dm++) { for (int dm = 0; dm < 3; dm++) {
if (xyz[dm] >= lwoc_root.center[dm] ) { if (xyz[dm] >= world.getLwocRoot().center[dm] ) {
indx += 1 << dm; indx += 1 << dm;
} }
} }
...@@ -245,7 +153,7 @@ public class LwocOctree implements Serializable { ...@@ -245,7 +153,7 @@ public class LwocOctree implements Serializable {
* @param check_existed - do not add duplicate scenes and nodes * @param check_existed - do not add duplicate scenes and nodes
* @return An octree node where scene is added or null if the world needs growing * @return An octree node where scene is added or null if the world needs growing
*/ */
public static LwocOctree addScene( public LwocOctree addScene(
LwocScene scene, LwocScene scene,
boolean check_existed boolean check_existed
) {// returns null and adds to pendingScenes if needs growing ) {// returns null and adds to pendingScenes if needs growing
...@@ -259,8 +167,8 @@ public class LwocOctree implements Serializable { ...@@ -259,8 +167,8 @@ public class LwocOctree implements Serializable {
} else { } else {
node.leaf.addScene(scene,check_existed); node.leaf.addScene(scene,check_existed);
// Check if leaf node requires splitting // Check if leaf node requires splitting
if (node.leaf.getScenes().size() > MAX_CAMERAS) { if (node.leaf.getScenes().size() > world.getMaxCameras()) {
if (node.hsize > MIN_HSIZE) { if (node.hsize > world.getMinHsize()) {
if (!check_existed || !pendingLeafNodes.contains(node)) { if (!check_existed || !pendingLeafNodes.contains(node)) {
addPendingLeafNode(node); addPendingLeafNode(node);
} }
...@@ -274,7 +182,7 @@ public class LwocOctree implements Serializable { ...@@ -274,7 +182,7 @@ public class LwocOctree implements Serializable {
* Tend to pending scenes list. Not thread-safe, should be run in a single-thread mode. * Tend to pending scenes list. Not thread-safe, should be run in a single-thread mode.
* @param check_existed - do not add duplicate scenes and nodes * @param check_existed - do not add duplicate scenes and nodes
*/ */
public static void tendPendingScenes( public void tendPendingScenes(
boolean check_existed boolean check_existed
) { ) {
if (pendingScenes.isEmpty()) { if (pendingScenes.isEmpty()) {
...@@ -295,7 +203,7 @@ public class LwocOctree implements Serializable { ...@@ -295,7 +203,7 @@ public class LwocOctree implements Serializable {
* Only adds mesh centers and grows the world if needed. * Only adds mesh centers and grows the world if needed.
* @param check_existed do not add duplicate meshes * @param check_existed do not add duplicate meshes
*/ */
public static void tendPendingMeshCentersOnly( public void tendPendingMeshCentersOnly(
boolean check_existed boolean check_existed
) { ) {
if (pendingMeshes.isEmpty()) { if (pendingMeshes.isEmpty()) {
...@@ -326,14 +234,14 @@ public class LwocOctree implements Serializable { ...@@ -326,14 +234,14 @@ public class LwocOctree implements Serializable {
* Should be run after tendPendingMeshCentersOnly(). * Should be run after tendPendingMeshCentersOnly().
* @param check_existed do not add duplicate meshes * @param check_existed do not add duplicate meshes
*/ */
public static void tendPendingMeshes( public void tendPendingMeshes(
boolean check_existed ) { boolean check_existed ) {
if (pendingMeshes.isEmpty()) { if (pendingMeshes.isEmpty()) {
return; // nothing to do return; // nothing to do
} else { } else {
for (LwocMesh mesh: pendingMeshes) { for (LwocMesh mesh: pendingMeshes) {
// int num_added = // int num_added =
lwoc_root.addMesh( world.lwoc_root.addMesh(
mesh, mesh,
check_existed); check_existed);
} }
...@@ -417,6 +325,7 @@ public class LwocOctree implements Serializable { ...@@ -417,6 +325,7 @@ public class LwocOctree implements Serializable {
xyz[dm] +=new_hsize * ((((nchild >> dm) & 1) > 0)? 1 : -1); xyz[dm] +=new_hsize * ((((nchild >> dm) & 1) > 0)? 1 : -1);
} }
children[nchild] = new LwocOctree( children[nchild] = new LwocOctree(
world,
this, this,
xyz, xyz,
new_hsize); new_hsize);
...@@ -481,41 +390,44 @@ public class LwocOctree implements Serializable { ...@@ -481,41 +390,44 @@ public class LwocOctree implements Serializable {
* until the specified point gets inside. Not thread safe, should run in single-thread mode * until the specified point gets inside. Not thread safe, should run in single-thread mode
* @param xyz The point to be included in the world. * @param xyz The point to be included in the world.
*/ */
public static void growXYZ(double [] xyz) { public void growXYZ(double [] xyz) {
while (!lwoc_root.contains(xyz)) {// already fits, do not grow while (!world.lwoc_root.contains(xyz)) {// already fits, do not grow
// grow once // grow once
int indx=0; //direction to grow int indx=0; //direction to grow
double [] new_center = new double[3]; double [] new_center = new double[3];
double [] root_center = world.lwoc_root.center;
double root_hsize = world.lwoc_root.hsize;
for (int dm = 0; dm < new_center.length; dm++) { for (int dm = 0; dm < new_center.length; dm++) {
if (xyz[dm] >= lwoc_root.center[dm] ) { if (xyz[dm] >= root_center[dm] ) {
indx += 1 << dm; indx += 1 << dm;
new_center[dm]= lwoc_root.center[dm] + lwoc_root.hsize; new_center[dm]= root_center[dm] + root_hsize;
} else { } else {
new_center[dm]= lwoc_root.center[dm] - lwoc_root.hsize; new_center[dm]= root_center[dm] - root_hsize;
} }
} }
LwocOctree new_root = new LwocOctree(null, new_center, lwoc_root.hsize * 2); LwocOctree new_root = new LwocOctree(world,null, new_center, world.lwoc_root.hsize * 2);
new_root.children = new LwocOctree[NUM_CHILDREN]; new_root.children = new LwocOctree[NUM_CHILDREN];
int child = (~indx ) & (NUM_CHILDREN -1); // opposite direction, from new root to old root int child = (~indx ) & (NUM_CHILDREN -1); // opposite direction, from new root to old root
for (int ichild = 0; ichild < NUM_CHILDREN; ichild++) { for (int ichild = 0; ichild < NUM_CHILDREN; ichild++) {
if (ichild == child) { if (ichild == child) {
lwoc_root.parent = new_root; world.lwoc_root.parent = new_root;
new_root.children[ichild] = lwoc_root; new_root.children[ichild] = world.lwoc_root;
} else { // create empty leaf nodes } else { // create empty leaf nodes
new_root.children[ichild] = new LwocOctree( new_root.children[ichild] = new LwocOctree(
world,
new_root, new_root,
new double [] { new double [] {
new_center[0] + lwoc_root.hsize * ((((child >> 0) & 1) > 0)? 1 : -1), new_center[0] + root_hsize * ((((child >> 0) & 1) > 0)? 1 : -1),
new_center[1] + lwoc_root.hsize * ((((child >> 1) & 1) > 0)? 1 : -1), new_center[1] + root_hsize * ((((child >> 1) & 1) > 0)? 1 : -1),
new_center[2] + lwoc_root.hsize * ((((child >> 2) & 1) > 0)? 1 : -1) new_center[2] + root_hsize * ((((child >> 2) & 1) > 0)? 1 : -1)
}, },
lwoc_root.hsize); root_hsize);
// add leaf // add leaf
new_root.children[ichild].leaf = new LwocLeaf(); new_root.children[ichild].leaf = new LwocLeaf();
} }
} }
lwoc_root = new_root; world.lwoc_root = new_root;
} }
} }
...@@ -525,6 +437,7 @@ public class LwocOctree implements Serializable { ...@@ -525,6 +437,7 @@ public class LwocOctree implements Serializable {
* @param half_whd half width(x), height(y) and depth(z) * @param half_whd half width(x), height(y) and depth(z)
* @return True if it intersects * @return True if it intersects
*/ */
//FIXME: obey border (on the edges of max hsize of the root) nodes
public boolean intersects ( public boolean intersects (
double [] xyz, double [] xyz,
double [] half_whd) { double [] half_whd) {
...@@ -544,6 +457,7 @@ public class LwocOctree implements Serializable { ...@@ -544,6 +457,7 @@ public class LwocOctree implements Serializable {
* @param xyz point * @param xyz point
* @return True if it intersects * @return True if it intersects
*/ */
//FIXME: obey border (on the edges of max hsize of the root) nodes
public boolean contains ( public boolean contains (
double [] xyz) { double [] xyz) {
for (int dm = 0; dm < center.length; dm++) { for (int dm = 0; dm < center.length; dm++) {
...@@ -563,6 +477,8 @@ public class LwocOctree implements Serializable { ...@@ -563,6 +477,8 @@ public class LwocOctree implements Serializable {
* @param half_whd half width(x), height(y) and depth(z) * @param half_whd half width(x), height(y) and depth(z)
* @return True if it intersects * @return True if it intersects
*/ */
//FIXME: obey border (on the edges of max hsize of the root) nodes
public boolean contains ( public boolean contains (
double [] xyz, double [] xyz,
double [] half_whd) { double [] half_whd) {
...@@ -584,7 +500,7 @@ public class LwocOctree implements Serializable { ...@@ -584,7 +500,7 @@ public class LwocOctree implements Serializable {
* @param check_existed Add only if the same mesh did not exist * @param check_existed Add only if the same mesh did not exist
* @return number of nodes it was added to (intersecting) * @return number of nodes it was added to (intersecting)
*/ */
public static boolean addMeshCenter( // returns 0 and adds to pendingMeshes if needs growing public boolean addMeshCenter( // returns 0 and adds to pendingMeshes if needs growing
LwocMesh mesh, LwocMesh mesh,
boolean check_existed boolean check_existed
) { ) {
...@@ -594,7 +510,7 @@ public class LwocOctree implements Serializable { ...@@ -594,7 +510,7 @@ public class LwocOctree implements Serializable {
double [] corner_xyz = center.clone(); double [] corner_xyz = center.clone();
for (int dm = 0; dm < center.length; dm++) { for (int dm = 0; dm < center.length; dm++) {
corner_xyz[dm] += dims[dm]; corner_xyz[dm] += dims[dm];
if (!lwoc_root.contains(corner_xyz)){ if (!world.lwoc_root.contains(corner_xyz)){
if (pendingMeshes != null) { if (pendingMeshes != null) {
if (!check_existed || !pendingMeshes.contains(mesh)) { if (!check_existed || !pendingMeshes.contains(mesh)) {
addPendingMesh(mesh); addPendingMesh(mesh);
...@@ -603,7 +519,7 @@ public class LwocOctree implements Serializable { ...@@ -603,7 +519,7 @@ public class LwocOctree implements Serializable {
return false; return false;
} }
corner_xyz[dm] -= 2*dims[dm]; corner_xyz[dm] -= 2*dims[dm];
if (!lwoc_root.contains(corner_xyz)){ if (!world.lwoc_root.contains(corner_xyz)){
if (pendingMeshes != null) { if (pendingMeshes != null) {
if (!check_existed || !pendingMeshes.contains(mesh)) { if (!check_existed || !pendingMeshes.contains(mesh)) {
addPendingMesh(mesh); addPendingMesh(mesh);
...@@ -617,8 +533,8 @@ public class LwocOctree implements Serializable { ...@@ -617,8 +533,8 @@ public class LwocOctree implements Serializable {
LwocOctree node = getLeafNode(center); LwocOctree node = getLeafNode(center);
node.leaf.addMeshCenter(mesh, check_existed); node.leaf.addMeshCenter(mesh, check_existed);
// Check if leaf node requires splitting // Check if leaf node requires splitting
if (node.leaf.getMeshCenters().size() > MAX_MESH_CENTERS) { if (node.leaf.getMeshCenters().size() > world.getMaxMeshCenters()) {
if (node.hsize > MIN_HSIZE) { if (node.hsize > world.getMinHsize()) {
if (!check_existed || !pendingLeafNodes.contains(node)) { if (!check_existed || !pendingLeafNodes.contains(node)) {
addPendingLeafNode(node); addPendingLeafNode(node);
} }
...@@ -659,7 +575,7 @@ public class LwocOctree implements Serializable { ...@@ -659,7 +575,7 @@ public class LwocOctree implements Serializable {
* Should fit in a root node (as it was earlier added) * Should fit in a root node (as it was earlier added)
* @param mesh new mesh to add * @param mesh new mesh to add
*/ */
public static void removeMeshCenter( public void removeMeshCenter(
LwocMesh mesh) { // check and remove duplicates LwocMesh mesh) { // check and remove duplicates
LwocOctree node = getLeafNode(mesh.getCenter()); LwocOctree node = getLeafNode(mesh.getCenter());
node.leaf.removeMeshCenter(mesh); node.leaf.removeMeshCenter(mesh);
...@@ -688,6 +604,26 @@ public class LwocOctree implements Serializable { ...@@ -688,6 +604,26 @@ public class LwocOctree implements Serializable {
return removed; return removed;
} }
/**
* Restore pointers to .parent and .world
* @param world
* @param parent
*/
public void restoreWorldParent(
LwocWorld world,
LwocOctree parent) {
this.parent = parent;
this.world = world;
if (!isLeaf()) {
for (LwocOctree child:children) {
child.restoreWorldParent(
world, // LwocWorld world,
this); // LwocOctree parent)
}
}
}
/** /**
* Recursively create a list of all leave nodes in the world. * Recursively create a list of all leave nodes in the world.
* @return A list of all leaf nodes * @return A list of all leaf nodes
...@@ -708,9 +644,9 @@ public class LwocOctree implements Serializable { ...@@ -708,9 +644,9 @@ public class LwocOctree implements Serializable {
* Rebuild meshes lists from mesh_centers for all leaf nodes after restoring the world. * Rebuild meshes lists from mesh_centers for all leaf nodes after restoring the world.
* Used after restoring world from serialized form * Used after restoring world from serialized form
*/ */
public static void rebuildMeshLists( public void rebuildMeshLists(
final boolean check_existed) { final boolean check_existed) {
final List<LwocOctree> leaves = lwoc_root.getAllLeafNodes(); final List<LwocOctree> leaves = world.lwoc_root.getAllLeafNodes();
final List<LwocMesh> meshes = new ArrayList<LwocMesh>(); final List<LwocMesh> meshes = new ArrayList<LwocMesh>();
for (LwocOctree node : leaves) { for (LwocOctree node : leaves) {
node.leaf.initMeshes(); node.leaf.initMeshes();
...@@ -726,7 +662,7 @@ public class LwocOctree implements Serializable { ...@@ -726,7 +662,7 @@ public class LwocOctree implements Serializable {
public void run() { public void run() {
for (int indx_mesh = ai.getAndIncrement(); indx_mesh < meshes.size(); indx_mesh = ai.getAndIncrement()) { for (int indx_mesh = ai.getAndIncrement(); indx_mesh < meshes.size(); indx_mesh = ai.getAndIncrement()) {
LwocMesh mesh = meshes.get(indx_mesh); LwocMesh mesh = meshes.get(indx_mesh);
lwoc_root.addMesh(mesh, check_existed); world.lwoc_root.addMesh(mesh, check_existed);
} }
} }
}; };
......
/**
**
** LwocWorld.java - Octree world parameters (previous static)
**
** Copyright (C) 2022 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** LwocWorld.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package com.elphel.imagej.tileprocessor.lwoc;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class LwocWorld implements Serializable {
private static final long serialVersionUID = 1L;
static List<LwocWorld> lwoc_worlds; //
public double min_hsize; // = 0.3; // meter - do not subdivide more
public double max_hsize; // = 10000.0; // meter - do not grow more
public int max_mesh_centers; // = 10; // maximal number of meshes in a leaf;
public int max_cameras; // = 10; // maximal number of cameras in a leaf;
// public transient LwocOctree lwoc_root; // = null;
public LwocOctree lwoc_root; // = null;
public double [] atr; // = null; // Azimuth, tilt, roll - may be used to merge
public double [] xyz; // = null; // this world offset (before rotation) or
// null if not known.
public LwocWorld (
double min_hsize,
double max_hsize,
int max_mesh_centers,
int max_cameras,
LwocOctree lwoc_root,
double [] atr,
double [] xyz) {
setMinHsize (min_hsize);
setMaxHsize (max_hsize);
setMaxMeshCenters(max_mesh_centers);
setMaxCameras (max_cameras);
setLwocRoot (lwoc_root);
setATR (atr);
setXYZ (xyz);
}
public double getMinHsize() {return min_hsize;}
public double getMaxHsize() {return max_hsize;}
public int getMaxMeshCenters() {return max_mesh_centers;}
public int getMaxCameras() {return max_cameras;}
public LwocOctree getLwocRoot() {return lwoc_root;}
public double [] getATR() {return atr;}
public double [] getXYZ() {return xyz;}
public void setMinHsize (double min_hsize) {this.min_hsize = min_hsize;}
public void setMaxHsize (double max_hsize) {this.max_hsize = max_hsize;}
public void setMaxMeshCenters(int max_mesh_centers) {this.max_mesh_centers = max_mesh_centers;}
public void setMaxCameras (int max_cameras) {this.max_cameras = max_cameras;}
public void setLwocRoot (LwocOctree lwoc_root) {this.lwoc_root = lwoc_root;}
public void setATR (double [] atr) {this.atr = atr;}
public void setXYZ (double [] xyz) {this.xyz = xyz;}
/**
* Serialize and write world to an output stream
* @param oos ObjectOutputStream to write to.
* @throws IOException
*/
private void writeObject(ObjectOutputStream oos)
throws IOException {
oos.defaultWriteObject();
// as of now - nothing else, custom for reads only
// if (parent == null) { // write world members
/*
oos.writeObject(world.getMinHsize());
oos.writeObject(world.getMaxHsize());
oos.writeObject(world.getMaxMeshCenters());
oos.writeObject(world.getMaxCameras());
oos.writeObject(world.getATR());
oos.writeObject(world.getXYZ());
*/
// oos.writeObject(world);
// Remove those
// oos.writeObject(OCTREE_ID.get());
// oos.writeObject(LwocMesh.MESH_ID.get());
// }
}
/**
* Read input stream and deserialize it to world octree structure.
* @param ois ObjectInputStream to read from
* @throws ClassNotFoundException
* @throws IOException
*/
private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
ois.defaultReadObject();
// now rebuild transient .parent and .world field for the whole tree
lwoc_root.restoreWorldParent(
this, // LwocWorld world,
null); //LwocOctree parent)
lwoc_root.rebuildMeshLists(
true); // final boolean check_existed)
}
/**
* Init worlds and their list. Multiple worlds may be needed if some world initially can not
* be matched. They will grow independently and possibly merged later
*/
public static void initWorlds() {
LwocMesh.resetMeshes();
LwocScene.resetScenes();
LwocOctree.resetPending();
lwoc_worlds = new ArrayList<LwocWorld>();
}
/**
* Create a new empty world and add it to the list of worlds in the universe.
* @param center X,Y,Z of the new world
* @param world_hsize new world half-size
* @param min_hsize do not subdivide nodes if half-size is smaller than this
* @param max_hsize do not grow world if its half-size it >= this
* @param max_mesh_centers maximal number of mesh centers in a node to trigger subdivision
* @param max_cameras maximal number of scenes (cameras) in a node to trigger subdivision
* @param atr world rotation relative to the universe (non-null when defined)
* @param xyz world offset in the universe (non-null when defined)
* @return new world instance
*/
public static LwocWorld newWorld(
double [] center,
double world_hsize,
double min_hsize,
double max_hsize,
int max_mesh_centers,
int max_cameras,
double [] atr,
double [] xyz) {
LwocWorld new_world = new LwocWorld (
min_hsize, // double min_hsize,
max_hsize, // double max_hsize,
max_mesh_centers, // int max_mesh_centers,
max_cameras, // int max_cameras,
null, // LwocOctree lwoc_root,
null, //double [] atr,
null); //double [] xyz);
LwocOctree root_node = new LwocOctree (
new_world, // LwocWorld lwocWorld,
null, // LwocOctree parent,
center, // double [] xyz,
world_hsize); //double hsize)
root_node.leaf = new LwocLeaf();
new_world.setLwocRoot(root_node);
lwoc_worlds.add(new_world);
return new_world;
}
/**
* Delete world from the universe (if existed)
* @param world world instance to remove
* @return True if removed, false if did not exist.
*/
public static boolean deleteWorld (LwocWorld world) {
return lwoc_worlds.remove(world);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment