blob: b13be9d22a48f362cbf67a4b1f50ddd4eadc8d64 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.addons.telecoms.ui.jme3.scene_objects;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import org.eclipse.apogy.addons.telecoms.AbstractAntennaRadiationPattern;
import org.eclipse.apogy.addons.telecoms.ui.AbstractAntennaRadiationPatternSceneObject;
import org.eclipse.apogy.common.topology.ui.jme3.JME3RenderEngineDelegate;
import org.eclipse.apogy.common.topology.ui.jme3.JME3Utilities;
import org.eclipse.apogy.common.topology.ui.jme3.scene_objects.DefaultJME3SceneObject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Mesh.Mode;
import com.jme3.util.BufferUtils;
public class AbstractAntennaRadiationPatternJME3Object extends DefaultJME3SceneObject<AbstractAntennaRadiationPattern>
implements AbstractAntennaRadiationPatternSceneObject {
private static final Logger Logger = LoggerFactory.getLogger(AbstractAntennaRadiationPatternJME3Object.class);
private final boolean useShading = true;
private boolean updatingGeometry = false;
private AssetManager assetManager;
private Geometry radiationPatternGeometry = null;
private com.jme3.scene.Mesh jme3mMesh = null;
// private MeshPresentationMode meshPresentationMode =
// MeshPresentationMode.SURFACE;
private final ColorRGBA meshColor = getDefaultMeshColor();
public AbstractAntennaRadiationPatternJME3Object(AbstractAntennaRadiationPattern abstractAntennaRadiationPattern,
JME3RenderEngineDelegate jme3RenderEngineDelegate) {
super(abstractAntennaRadiationPattern, jme3RenderEngineDelegate);
if (abstractAntennaRadiationPattern == null || jme3RenderEngineDelegate == null) {
throw new IllegalArgumentException();
}
this.assetManager = this.jme3Application.getAssetManager();
// Updates the geometry.
Job job = new Job("AbstractAntennaRadiationPatternJME3Object : Updating Geometry.") {
@Override
protected IStatus run(IProgressMonitor monitor) {
// Creates the new mesh.
final Mesh newMesh = createMesh(abstractAntennaRadiationPattern);
AbstractAntennaRadiationPatternJME3Object.this.jme3Application.enqueue(new Callable<Object>() {
@Override
public Object call() throws Exception {
updateGeometryInternal(newMesh);
return null;
}
});
return Status.OK_STATUS;
}
};
job.schedule();
}
@Override
public void updateGeometry(float tpf) {
com.jme3.scene.Mesh mesh = createMesh(getTopologyNode());
updateGeometryInternal(mesh);
}
@Override
public List<Geometry> getGeometries() {
List<Geometry> geometries = new ArrayList<Geometry>();
geometries.add(this.radiationPatternGeometry);
return geometries;
}
@Override
public void dispose() {
super.dispose();
}
/**
* Updates geometry. NOT THREAD SAFE.
*/
private void updateGeometryInternal(final Mesh newMesh) {
try {
if (!this.updatingGeometry) {
this.updatingGeometry = true;
// Detach previous geometry if required.
if (this.radiationPatternGeometry != null) {
getAttachmentNode().detachChild(this.radiationPatternGeometry);
}
this.jme3mMesh = newMesh;
// Updates the mesh if applicable.
if (this.jme3mMesh != null) {
if (getTopologyNode().getNodeId() != null) {
this.radiationPatternGeometry = new Geometry(getTopologyNode().getNodeId(), this.jme3mMesh);
} else {
this.radiationPatternGeometry = new Geometry("AbstractAntennaRadiationPattern", this.jme3mMesh);
}
this.radiationPatternGeometry.setMaterial(createMaterial());
this.radiationPatternGeometry.setShadowMode(ShadowMode.CastAndReceive);
getAttachmentNode().attachChild(this.radiationPatternGeometry);
}
this.updatingGeometry = false;
}
} catch (Throwable t) {
Logger.error(t.getMessage(), t);
}
}
private Material createMaterial() {
Material mat = null;
if (this.useShading) {
mat = new Material(this.assetManager, "Common/MatDefs/Light/Lighting.j3md");
if (this.meshColor != null) {
mat.setColor("Diffuse", this.meshColor);
mat.setColor("Ambient", this.meshColor);
mat.setColor("Specular", this.meshColor);
}
mat.setFloat("Shininess", 64f);
mat.setBoolean("UseMaterialColors", true);
} else {
mat = new Material(this.assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
if (this.meshColor != null) {
mat.setColor("Color", this.meshColor);
}
}
return mat;
}
private com.jme3.scene.Mesh createMesh(AbstractAntennaRadiationPattern abstractAntennaRadiationPattern) {
List<Vector3f> verticeList = new ArrayList<Vector3f>();
double thetaIncrement = Math.toRadians(10);
double phiIncrement = Math.toRadians(10);
double theta = 0;
while (theta <= Math.PI) {
double phi = -Math.PI;
while (phi <= Math.PI) {
double gain = abstractAntennaRadiationPattern.computeGain(theta, phi);
double r = Math.pow(10, gain / 10.0);
float x = (float) (r * Math.sin(theta) * Math.cos(phi));
float y = (float) (r * Math.sin(theta) * Math.sin(phi));
float z = (float) (r * Math.cos(theta));
Vector3f v = new Vector3f(x, y, z);
verticeList.add(v);
phi += phiIncrement;
}
theta += thetaIncrement;
}
Mesh mesh = new Mesh();
mesh.setMode(Mode.Points);
mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Position, 3,
BufferUtils.createFloatBuffer(JME3Utilities.convertToFloatArray(verticeList)));
// mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Index, 3, BufferUtils.createIntBuffer(JME3Utilities.convertToIntArray(indexesList)));
// mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.Normal, 3, BufferUtils.createFloatBuffer(JME3Utilities.convertToFloatArray(normalslList)));
// mesh.setBuffer(com.jme3.scene.VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(textureCoordArray));
mesh.updateBound();
mesh.updateCounts();
return mesh;
}
private ColorRGBA getDefaultMeshColor() {
// ColorRGBA rgba = null;
//
// IPreferenceStore store = org.eclipse.apogy.common.geometry.data3d.ui.Activator.getDefault().getPreferenceStore();
//
// // Change color.
// RGB rgb = PreferenceConverter.getColor(store, MRTData3DUIPreferencesConstants.DEFAULT_TRIANGULAR_MESH_COLOR_ID);
//
// if(rgb != null)
// {
// rgba = JME3Utilities.convertToColorRGBA(rgb);
// }
// else
// {
// rgba = new ColorRGBA(1.0f, 0f, 0.0f, 1.0f);
// }
//
// return rgba;
return new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f);
}
}