use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.
the class ParticleGroupPointRenderSystem method renderObject.
@Override
protected void renderObject(ExtShaderProgram shaderProgram, IRenderable renderable) {
final ParticleGroup particleGroup = (ParticleGroup) renderable;
synchronized (particleGroup) {
if (!particleGroup.disposed) {
boolean hlCmap = particleGroup.isHighlighted() && !particleGroup.isHlplain();
if (!inGpu(particleGroup)) {
int offset = addMeshData(particleGroup.size());
setOffset(particleGroup, offset);
curr = meshes.get(offset);
float[] c = particleGroup.getColor();
float[] colorMin = particleGroup.getColorMin();
float[] colorMax = particleGroup.getColorMax();
double minDistance = particleGroup.getMinDistance();
double maxDistance = particleGroup.getMaxDistance();
ensureTempVertsSize(particleGroup.size() * curr.vertexSize);
int n = particleGroup.data().size();
int numAdded = 0;
for (int i = 0; i < n; i++) {
if (particleGroup.filter(i) && particleGroup.isVisible(i)) {
IParticleRecord pb = particleGroup.get(i);
double[] p = pb.rawDoubleData();
// COLOR
if (particleGroup.isHighlighted()) {
if (hlCmap) {
// Color map
double[] color = cmap.colormap(particleGroup.getHlcmi(), particleGroup.getHlcma().get(pb), particleGroup.getHlcmmin(), particleGroup.getHlcmmax());
tempVerts[curr.vertexIdx + curr.colorOffset] = Color.toFloatBits((float) color[0], (float) color[1], (float) color[2], 1.0f);
} else {
// Plain
tempVerts[curr.vertexIdx + curr.colorOffset] = Color.toFloatBits(c[0], c[1], c[2], c[3]);
}
} else {
if (colorMin != null && colorMax != null) {
double dist = Math.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]);
// fac = 0 -> colorMin, fac = 1 -> colorMax
double fac = (dist - minDistance) / (maxDistance - minDistance);
interpolateColor(colorMin, colorMax, c, fac);
}
float r = 0, g = 0, b = 0;
if (particleGroup.colorNoise != 0) {
r = (float) ((StdRandom.uniform() - 0.5) * 2.0 * particleGroup.colorNoise);
g = (float) ((StdRandom.uniform() - 0.5) * 2.0 * particleGroup.colorNoise);
b = (float) ((StdRandom.uniform() - 0.5) * 2.0 * particleGroup.colorNoise);
}
tempVerts[curr.vertexIdx + curr.colorOffset] = Color.toFloatBits(MathUtils.clamp(c[0] + r, 0, 1), MathUtils.clamp(c[1] + g, 0, 1), MathUtils.clamp(c[2] + b, 0, 1), MathUtils.clamp(c[3], 0, 1));
}
// SIZE, CMAP_VALUE
tempVerts[curr.vertexIdx + additionalOffset] = (particleGroup.size + (float) (rand.nextGaussian() * particleGroup.size / 5d)) * particleGroup.highlightedSizeFactor();
// POSITION
final int idx = curr.vertexIdx;
tempVerts[idx] = (float) p[0];
tempVerts[idx + 1] = (float) p[1];
tempVerts[idx + 2] = (float) p[2];
curr.vertexIdx += curr.vertexSize;
numAdded++;
}
}
int count = numAdded * curr.vertexSize;
setCount(particleGroup, count);
curr.mesh.setVertices(tempVerts, 0, count);
setInGpu(particleGroup, true);
}
curr = meshes.get(getOffset(particleGroup));
if (curr != null) {
float meanDist = (float) (particleGroup.getMeanDistance());
shaderProgram.setUniformf("u_alpha", alphas[particleGroup.ct.getFirstOrdinal()] * particleGroup.getOpacity());
shaderProgram.setUniformf("u_falloff", particleGroup.profileDecay);
shaderProgram.setUniformf("u_sizeFactor", (float) ((((stereoHalfWidth ? 2.0 : 1.0) * rc.scaleFactor * StarSettings.getStarPointSize() * 0.5)) * particleGroup.highlightedSizeFactor() * meanDist / (camera.getFovFactor() * Constants.DISTANCE_SCALE_FACTOR)));
shaderProgram.setUniformf("u_sizeLimits", (float) (particleGroup.particleSizeLimitsPoint[0] / camera.getFovFactor()), (float) (particleGroup.particleSizeLimitsPoint[1] / camera.getFovFactor()));
curr.mesh.render(shaderProgram, ShapeType.Point.getGlType());
}
}
}
}
use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.
the class ParticleGroupRenderSystem method renderObject.
@Override
protected void renderObject(ExtShaderProgram shaderProgram, IRenderable renderable) {
final ParticleGroup particleGroup = (ParticleGroup) renderable;
synchronized (particleGroup) {
if (!particleGroup.disposed) {
boolean hlCmap = particleGroup.isHighlighted() && !particleGroup.isHlplain();
if (!inGpu(particleGroup)) {
int n = particleGroup.size();
int offset = addMeshData(n * 4, n * 6);
setOffset(particleGroup, offset);
curr = meshes.get(offset);
ensureTempVertsSize(n * 4 * curr.vertexSize);
ensureTempIndicesSize(n * 6);
float[] c = particleGroup.getColor();
float[] colorMin = particleGroup.getColorMin();
float[] colorMax = particleGroup.getColorMax();
double minDistance = particleGroup.getMinDistance();
double maxDistance = particleGroup.getMaxDistance();
int numVerticesAdded = 0;
int numParticlesAdded = 0;
for (int i = 0; i < n; i++) {
if (particleGroup.filter(i) && particleGroup.isVisible(i)) {
IParticleRecord particle = particleGroup.get(i);
double[] p = particle.rawDoubleData();
// 4 vertices per particle
for (int vert = 0; vert < 4; vert++) {
// Vertex POSITION
tempVerts[curr.vertexIdx + posOffset] = vertPos[vert].getFirst();
tempVerts[curr.vertexIdx + posOffset + 1] = vertPos[vert].getSecond();
// UV coordinates
tempVerts[curr.vertexIdx + uvOffset] = vertUV[vert].getFirst();
tempVerts[curr.vertexIdx + uvOffset + 1] = vertUV[vert].getSecond();
// COLOR
if (particleGroup.isHighlighted()) {
if (hlCmap) {
// Color map
double[] color = cmap.colormap(particleGroup.getHlcmi(), particleGroup.getHlcma().get(particle), particleGroup.getHlcmmin(), particleGroup.getHlcmmax());
tempVerts[curr.vertexIdx + curr.colorOffset] = Color.toFloatBits((float) color[0], (float) color[1], (float) color[2], 1.0f);
} else {
// Plain
tempVerts[curr.vertexIdx + curr.colorOffset] = Color.toFloatBits(c[0], c[1], c[2], c[3]);
}
} else {
if (colorMin != null && colorMax != null) {
double dist = Math.sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]);
// fac = 0 -> colorMin, fac = 1 -> colorMax
double fac = (dist - minDistance) / (maxDistance - minDistance);
interpolateColor(colorMin, colorMax, c, fac);
}
float r = 0, g = 0, b = 0;
if (particleGroup.colorNoise != 0) {
r = (float) ((StdRandom.uniform() - 0.5) * 2.0 * particleGroup.colorNoise);
g = (float) ((StdRandom.uniform() - 0.5) * 2.0 * particleGroup.colorNoise);
b = (float) ((StdRandom.uniform() - 0.5) * 2.0 * particleGroup.colorNoise);
}
tempVerts[curr.vertexIdx + curr.colorOffset] = Color.toFloatBits(MathUtils.clamp(c[0] + r, 0, 1), MathUtils.clamp(c[1] + g, 0, 1), MathUtils.clamp(c[2] + b, 0, 1), MathUtils.clamp(c[3], 0, 1));
}
// SIZE
tempVerts[curr.vertexIdx + sizeOffset] = (particleGroup.size + (float) (rand.nextGaussian() * particleGroup.size / 5d)) * particleGroup.highlightedSizeFactor();
// PARTICLE POSITION
tempVerts[curr.vertexIdx + particlePosOffset] = (float) p[0];
tempVerts[curr.vertexIdx + particlePosOffset + 1] = (float) p[1];
tempVerts[curr.vertexIdx + particlePosOffset + 2] = (float) p[2];
curr.vertexIdx += curr.vertexSize;
curr.numVertices++;
numVerticesAdded++;
}
// Indices
quadIndices(curr);
numParticlesAdded++;
}
}
int count = numVerticesAdded * curr.vertexSize;
setCount(particleGroup, count);
curr.mesh.setVertices(tempVerts, 0, count);
curr.mesh.setIndices(tempIndices, 0, numParticlesAdded * 6);
setInGpu(particleGroup, true);
}
/*
* RENDER
*/
curr = meshes.get(getOffset(particleGroup));
if (curr != null) {
float meanDist = (float) (particleGroup.getMeanDistance());
double s = .3e-4f;
shaderProgram.setUniformf("u_alpha", alphas[particleGroup.ct.getFirstOrdinal()] * particleGroup.getOpacity());
shaderProgram.setUniformf("u_falloff", particleGroup.profileDecay);
shaderProgram.setUniformf("u_sizeFactor", (float) (((StarSettings.getStarPointSize() * s)) * particleGroup.highlightedSizeFactor() * meanDist / Constants.DISTANCE_SCALE_FACTOR));
shaderProgram.setUniformf("u_sizeLimits", (float) (particleGroup.particleSizeLimits[0] * particleGroup.highlightedSizeFactor()), (float) (particleGroup.particleSizeLimits[1] * particleGroup.highlightedSizeFactor()));
try {
curr.mesh.render(shaderProgram, GL20.GL_TRIANGLES);
} catch (IllegalArgumentException e) {
logger.error(e, "Render exception");
}
}
}
}
}
use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.
the class OctreeGeneratorRun method generateOctree.
private OctreeNode generateOctree() throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
long startMs = TimeUtils.millis();
OctreeGeneratorParams ogp = new OctreeGeneratorParams(maxPart, postprocess, childCount, parentCount);
IOctreeGenerator og = new OctreeGeneratorMag(ogp);
List<IParticleRecord> listLoader = null, list;
Map<Long, Integer> xmatchTable = null;
long[] countsPerMagGaia = null;
//
if (loaderClass != null) {
String fullLoaderClass = "gaiasky.data.group." + loaderClass;
IStarGroupDataProvider loader = (IStarGroupDataProvider) Class.forName(fullLoaderClass).getDeclaredConstructor().newInstance();
loader.setOutputFormatVersion(outputVersion);
loader.setColumns(columns);
loader.setParallaxErrorFactorFaint(plxerrfaint);
loader.setParallaxErrorFactorBright(plxerrbright);
loader.setParallaxZeroPoint(plxzeropoint);
loader.setFileNumberCap(fileNumCap);
loader.setStarNumberCap(starNumCap);
loader.setDistanceCap(distPcCap);
loader.setAdditionalFiles(additionalFiles);
loader.setRUWECap(ruwe);
countsPerMagGaia = loader.getCountsPerMag();
if (hip != null && xmatchFile != null && !xmatchFile.isEmpty()) {
// Load xmatchTable
xmatchTable = readXmatchTable(xmatchFile);
if (!xmatchTable.isEmpty()) {
// IDs which must be loaded regardless (we need them to update x-matched HIP stars)
loader.setMustLoadIds(new HashSet<>(xmatchTable.keySet()));
}
}
/* LOAD CATALOG */
listLoader = loader.loadData(input);
}
//
if (hip != null) {
STILDataProvider stil = new STILDataProvider();
// All hip stars for which we have a Gaia star, bypass plx >= 0 condition in STILDataProvider
if (xmatchTable != null && !xmatchTable.isEmpty()) {
Set<Long> mustLoad = new HashSet<>();
for (int hipNumber : xmatchTable.values()) {
mustLoad.add(Long.valueOf(hipNumber));
}
stil.setMustLoadIds(mustLoad);
}
List<IParticleRecord> listHip = stil.loadData(hip);
// Update HIP names using external source, if needed
if (hipNamesDir != null) {
HipNames hipNames = new HipNames();
hipNames.load(Paths.get(hipNamesDir));
Map<Integer, Array<String>> hn = hipNames.getHipNames();
for (IParticleRecord pb : listHip) {
IParticleRecord star = pb;
if (hn.containsKey(star.hip())) {
Array<String> names = hn.get(star.hip());
for (String name : names) star.addName(name);
}
}
}
// Combine counts per magnitude
long[] countsPerMagHip = stil.getCountsPerMag();
combineCountsPerMag(countsPerMagGaia, countsPerMagHip);
// Create HIP map
Map<Integer, IParticleRecord> hipMap = new HashMap<>();
for (IParticleRecord star : listHip) {
hipMap.put(star.hip(), star);
}
// Check x-match file
int hipnum = listHip.size();
int starhits = 0;
int notFoundHipStars = 0;
Vector3d aux1 = new Vector3d();
Vector3d aux2 = new Vector3d();
if (listLoader != null) {
for (IParticleRecord pb : listLoader) {
IParticleRecord gaiaStar = pb;
// Check if star is also in HIP catalog
if (xmatchTable == null || !xmatchTable.containsKey(gaiaStar.id())) {
// No hit, add to main list
listHip.add(gaiaStar);
} else {
// Update hipStar using gaiaStar data, only when:
int hipId = xmatchTable.get(gaiaStar.id());
if (hipMap.containsKey(hipId)) {
// Hip Star
IParticleRecord hipStar = hipMap.get(hipId);
// Check parallax errors
Double gaiaPllxErr = gaiaStar.getExtra("pllx_err");
Double hipPllxErr = hipStar.getExtra("e_plx");
if (gaiaPllxErr <= hipPllxErr) {
// SIZE
float size = gaiaStar.size();
// POSITION
double x = gaiaStar.x(), y = gaiaStar.y(), z = gaiaStar.z();
aux1.set(x, y, z);
boolean negativeGaiaDistance = Math.abs(aux1.len() - AbstractStarGroupDataProvider.NEGATIVE_DIST) < 1e-10;
if (negativeGaiaDistance) {
// Negative distance in Gaia star!
// Use Gaia position, HIP distance and name(s)
// Fetch Gaia RA/DEC
Coordinates.cartesianToSpherical(aux1, aux2);
double gaiaRA = aux2.x;
double gaiaDEC = aux2.y;
// Fetch HIP distance
aux1.set(hipStar.x(), hipStar.y(), hipStar.z());
Coordinates.cartesianToSpherical(aux1, aux2);
double hipDIST = aux2.z;
// Compute new cartesian position
aux1.set(gaiaRA, gaiaDEC, hipDIST);
Coordinates.sphericalToCartesian(aux1, aux2);
x = aux2.x;
y = aux2.y;
z = aux2.z;
size = hipStar.size();
}
hipStar.setId(gaiaStar.id());
hipStar.setPos(x, y, z);
hipStar.setVelocityVector(gaiaStar.pmx(), gaiaStar.pmy(), gaiaStar.pmz());
hipStar.setProperMotion(gaiaStar.mualpha(), gaiaStar.mudelta(), gaiaStar.radvel());
hipStar.setMag(gaiaStar.appmag(), gaiaStar.absmag());
hipStar.setCol(gaiaStar.col());
hipStar.setSize(size);
hipStar.addNames(gaiaStar.names());
starhits++;
}
} else {
notFoundHipStars++;
}
}
}
logger.info(starhits + " of " + hipnum + " HIP stars' data updated due to being matched to a Gaia star (" + notFoundHipStars + " not found - negative parallax?)");
// Free up some memory
listLoader.clear();
}
// Main list is listHip
list = listHip;
} else {
list = listLoader;
}
if (list == null || list.isEmpty()) {
logger.info("No stars were loaded, please check out the parameters");
return null;
}
long loadingMs = TimeUtils.millis();
double loadingSecs = ((loadingMs - startMs) / 1000.0);
logger.info("TIME STATS: Data loaded in " + loadingSecs + " seconds");
logger.info("Generating octree with " + list.size() + " actual stars");
// Pre-processing (sorting, removing too distant stars)
Vector3d pos0 = new Vector3d();
Iterator<IParticleRecord> it = list.iterator();
while (it.hasNext()) {
IParticleRecord s = it.next();
double dist = pos0.set(s.x(), s.y(), s.z()).len();
if (dist * Constants.U_TO_PC > distPcCap) {
// Remove star
it.remove();
}
}
logger.info("Sorting list by magnitude with " + list.size() + " objects");
list.sort(new StarBrightnessComparator());
logger.info("Catalog sorting done");
OctreeNode octree = og.generateOctree(list);
PrintStream out = new PrintStream(System.out, true, StandardCharsets.UTF_8);
out.println(octree.toString(true));
long generatingMs = TimeUtils.millis();
double generatingSecs = ((generatingMs - loadingMs) / 1000.0);
logger.info("TIME STATS: Octree generated in " + generatingSecs + " seconds");
/**
* NUMBERS *
*/
logger.info("Octree generated with " + octree.numNodesRec() + " octants and " + octree.numObjectsRec + " particles");
logger.info(og.getDiscarded() + " particles have been discarded due to density");
/**
* CLEAN CURRENT OUT DIR *
*/
File metadataFile = new File(outFolder, "metadata.bin");
delete(metadataFile);
File particlesFolder = new File(outFolder, "particles/");
delete(particlesFolder);
/**
* WRITE METADATA *
*/
metadataFile.createNewFile();
logger.info("Writing metadata (" + octree.numNodesRec() + " nodes): " + metadataFile.getAbsolutePath());
MetadataBinaryIO metadataWriter = new MetadataBinaryIO();
metadataWriter.writeMetadata(octree, new FileOutputStream(metadataFile));
/**
* WRITE PARTICLES *
*/
IStarGroupIO particleWriter = new StarGroupBinaryIO();
particlesFolder.mkdirs();
int version = outputVersion < BinaryDataProvider.MIN_OUTPUT_VERSION || outputVersion > BinaryDataProvider.MAX_OUTPUT_VERSION ? BinaryDataProvider.DEFAULT_OUTPUT_VERSION : outputVersion;
logger.info("Using output format version " + version);
writeParticlesToFiles(particleWriter, octree, version);
long writingMs = TimeUtils.millis();
double writingSecs = (writingMs - generatingMs) / 1000.0;
double totalSecs = loadingSecs + generatingSecs + writingSecs;
int[][] stats = octree.stats();
NumberFormat formatter = new DecimalFormat("##########0.0000");
if (countsPerMagGaia != null) {
logger.info("=========================");
logger.info("STAR COUNTS PER MAGNITUDE");
logger.info("=========================");
for (int level = 0; level < countsPerMagGaia.length; level++) {
logger.info("Magnitude " + level + ": " + countsPerMagGaia[level] + " stars (" + formatter.format((double) countsPerMagGaia[level] * 100d / (double) list.size()) + "%)");
}
logger.info();
}
logger.info("============");
logger.info("OCTREE STATS");
logger.info("============");
logger.info("Octants: " + octree.numNodesRec());
logger.info("Particles: " + list.size());
logger.info("Depth: " + octree.getMaxDepth());
int level = 0;
for (int[] levelinfo : stats) {
logger.info(" Level " + level + ": " + levelinfo[0] + " octants, " + levelinfo[1] + " stars (" + formatter.format((double) levelinfo[1] * 100d / (double) list.size()) + "%)");
level++;
}
logger.info();
logger.info("================");
logger.info("FINAL TIME STATS");
logger.info("================");
logger.info("Loading: " + loadingSecs + " secs (" + formatTimeSecs((long) loadingSecs) + ")");
logger.info("Generating: " + generatingSecs + " secs (" + formatTimeSecs((long) generatingSecs) + ")");
logger.info("Writing: " + writingSecs + " secs (" + formatTimeSecs((long) writingSecs) + ")");
logger.info("Total: " + totalSecs + " secs (" + formatTimeSecs((long) totalSecs) + ")");
return octree;
}
use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.
the class SDSSDataProvider method loadFromBufferedReader.
private void loadFromBufferedReader(BufferedReader br, List<IParticleRecord> pointData) throws IOException {
String line;
int tokenslen;
while ((line = br.readLine()) != null) {
if (!line.isEmpty() && !line.startsWith("#")) {
// Read line
String[] tokens = line.split(",");
tokenslen = tokens.length;
double[] point = new double[tokenslen];
double ra = Parser.parseDouble(tokens[0]);
double dec = Parser.parseDouble(tokens[1]);
double z = Parser.parseDouble(tokens[2]);
if (z >= 0) {
// Dist in MPC
double dist = ((z * 299792.46) / 71);
if (dist > 16) {
// Convert position
Position p = new Position(ra, "deg", dec, "deg", dist, "mpc", PositionType.EQ_SPH_DIST);
p.gsposition.scl(Constants.PC_TO_U);
point[0] = p.gsposition.x;
point[1] = p.gsposition.y;
point[2] = p.gsposition.z;
pointData.add(new ParticleRecord(point));
}
}
}
}
}
use of gaiasky.scenegraph.particle.IParticleRecord in project gaiasky by langurmonkey.
the class UncertaintiesProvider method loadData.
@Override
public List<IParticleRecord> loadData(InputStream is, double factor) {
List<IParticleRecord> pointData = new ArrayList<>();
try {
int tokenslen;
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
Vector3d pos = new Vector3d();
while ((line = br.readLine()) != null) {
if (!line.isEmpty() && !line.startsWith("#")) {
// Read line
String[] tokens = line.split("\\s+");
tokenslen = tokens.length;
double[] point = new double[tokenslen];
for (int j = 0; j < tokenslen; j++) {
point[j] = Parser.parseDouble(tokens[j]) * factor;
}
pos.set(point[1], point[2], (point[0] + 8));
pos.mul(Coordinates.galToEq());
pos.scl(Constants.KPC_TO_U);
point[0] = pos.x;
point[1] = pos.y;
point[2] = pos.z;
pointData.add(new ParticleRecord(point));
}
}
br.close();
} catch (Exception e) {
logger.error(e);
return null;
}
return pointData;
}
Aggregations