Render motors nicely
This commit is contained in:
parent
05ff94836f
commit
ceb7d16651
BIN
core/resources/datafiles/textures/motors/aerotech.png
Normal file
BIN
core/resources/datafiles/textures/motors/aerotech.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
core/resources/datafiles/textures/motors/estes.png
Normal file
BIN
core/resources/datafiles/textures/motors/estes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
@ -10,19 +10,19 @@ import net.sf.openrocket.util.MathUtil;
|
||||
* @author Bill Kuker <bkuker@billkuker.com>
|
||||
*/
|
||||
public class Appearance {
|
||||
public static final Appearance MISSING = new Appearance(new Color(0, 0, 0), 100, null);
|
||||
public static final Appearance MISSING = new Appearance(new Color(0, 0, 0), 1, null);
|
||||
|
||||
private final Color paint;
|
||||
private final double shine;
|
||||
private final Decal texture;
|
||||
|
||||
Appearance(final Color paint, final double shine, final Decal texture) {
|
||||
public Appearance(final Color paint, final double shine, final Decal texture) {
|
||||
this.paint = paint;
|
||||
this.shine = MathUtil.clamp(shine, 0, 1);
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
Appearance(final Color paint, final double shine) {
|
||||
public Appearance(final Color paint, final double shine) {
|
||||
this.paint = paint;
|
||||
this.shine = MathUtil.clamp(shine, 0, 1);
|
||||
this.texture = null;
|
||||
|
@ -9,25 +9,27 @@ import net.sf.openrocket.util.Coordinate;
|
||||
* @author Bill Kuker <bkuker@billkuker.com>
|
||||
*/
|
||||
public class Decal {
|
||||
|
||||
|
||||
public static enum EdgeMode {
|
||||
REPEAT("TextureWrap.Repeat"), MIRROR("TextureWrap.Mirror"), CLAMP("TextureWrap.Clamp"), STICKER("TextureWrap.Sticker");
|
||||
private final String transName;
|
||||
EdgeMode(final String name){
|
||||
|
||||
EdgeMode(final String name) {
|
||||
this.transName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
public String toString() {
|
||||
return Application.getTranslator().get(transName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final Coordinate offset, center, scale;
|
||||
private final double rotation;
|
||||
private final DecalImage image;
|
||||
private final EdgeMode mode;
|
||||
|
||||
Decal(final Coordinate offset, final Coordinate center, final Coordinate scale, final double rotation,
|
||||
public Decal(final Coordinate offset, final Coordinate center, final Coordinate scale, final double rotation,
|
||||
final DecalImage image, final EdgeMode mode) {
|
||||
this.offset = offset;
|
||||
this.center = center;
|
||||
@ -36,35 +38,35 @@ public class Decal {
|
||||
this.image = image;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
|
||||
public Coordinate getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
public Coordinate getCenter() {
|
||||
return center;
|
||||
}
|
||||
|
||||
|
||||
public Coordinate getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
|
||||
public double getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
|
||||
public EdgeMode getEdgeMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
public DecalImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Texture [offset=" + offset + ", center=" + center + ", scale=" + scale + ", rotation=" + rotation
|
||||
+ ", image=" + image + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
package net.sf.openrocket.appearance.defaults;
|
||||
|
||||
import net.sf.openrocket.appearance.Appearance;
|
||||
import net.sf.openrocket.appearance.Decal;
|
||||
import net.sf.openrocket.appearance.Decal.EdgeMode;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
public class MotorAppearance extends Appearance {
|
||||
|
||||
|
||||
private static MotorAppearance ESTES = new MotorAppearance("/datafiles/textures/motors/estes.png");
|
||||
private static MotorAppearance AEROTECH = new MotorAppearance("/datafiles/textures/motors/aerotech.png");
|
||||
|
||||
public static Appearance getAppearance(Motor m) {
|
||||
if (m instanceof ThrustCurveMotor) {
|
||||
ThrustCurveMotor tcm = (ThrustCurveMotor) m;
|
||||
if ("Estes".equals(tcm.getManufacturer().getSimpleName())) {
|
||||
return ESTES;
|
||||
}
|
||||
if ("AeroTech".equals(tcm.getManufacturer().getSimpleName())) {
|
||||
return AEROTECH;
|
||||
}
|
||||
}
|
||||
return Appearance.MISSING;
|
||||
}
|
||||
|
||||
protected MotorAppearance(final String resource) {
|
||||
super(
|
||||
new Color(0, 0, 0),
|
||||
.1,
|
||||
new Decal(
|
||||
new Coordinate(0, 0),
|
||||
new Coordinate(0, 0),
|
||||
new Coordinate(1, 1),
|
||||
0,
|
||||
new ResourceDecalImage(resource), EdgeMode.REPEAT));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package net.sf.openrocket.appearance.defaults;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import net.sf.openrocket.appearance.DecalImage;
|
||||
|
||||
public class ResourceDecalImage implements DecalImage {
|
||||
final String resource;
|
||||
|
||||
ResourceDecalImage(final String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBytes() throws FileNotFoundException, IOException {
|
||||
return this.getClass().getResourceAsStream(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportImage(File file, boolean watchForChanges) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,7 @@ import javax.media.opengl.glu.GLUtessellatorCallback;
|
||||
import javax.media.opengl.glu.GLUtessellatorCallbackAdapter;
|
||||
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
@ -314,10 +315,9 @@ public class ComponentRenderer {
|
||||
|
||||
}
|
||||
|
||||
public void renderMotor(final GL2 gl, final Coordinate c, double l, double r) {
|
||||
final float outside[] = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_DIFFUSE, outside, 0);
|
||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, outside, 0);
|
||||
public void renderMotor(final GL2 gl, final Coordinate c, Motor motor) {
|
||||
double l = motor.getLength();
|
||||
double r = motor.getDiameter() / 2;
|
||||
|
||||
gl.glPushMatrix();
|
||||
|
||||
@ -325,15 +325,48 @@ public class ComponentRenderer {
|
||||
|
||||
gl.glRotated(90, 0, 1.0, 0);
|
||||
|
||||
gl.glMatrixMode(GL.GL_TEXTURE);
|
||||
gl.glPushMatrix();
|
||||
gl.glTranslated(0, .125, 0);
|
||||
gl.glScaled(1, .75, 0);
|
||||
|
||||
glu.gluCylinder(q, r, r, l, LOD, 1);
|
||||
|
||||
glu.gluDisk(q, r, 0, LOD, 2);
|
||||
gl.glPopMatrix();
|
||||
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
|
||||
|
||||
{
|
||||
final double da = (2.0f * Math.PI) / LOD;
|
||||
final double dt = 1.0 / LOD;
|
||||
gl.glBegin(GL.GL_TRIANGLE_STRIP);
|
||||
gl.glNormal3d(0, 0, 1);
|
||||
for (int i = 0; i < LOD + 1; i++) {
|
||||
gl.glTexCoord2d(i * dt, .125);
|
||||
gl.glVertex3d(r * Math.cos(da * i), r * Math.sin(da * i), 0);
|
||||
gl.glTexCoord2d(i * dt, 0);
|
||||
gl.glVertex3d(0, 0, 0);
|
||||
|
||||
}
|
||||
gl.glEnd();
|
||||
}
|
||||
|
||||
gl.glTranslated(0, 0, l);
|
||||
gl.glRotated(180, 0, 1.0, 0);
|
||||
|
||||
glu.gluDisk(q, r, 0, LOD, 2);
|
||||
|
||||
{
|
||||
final double da = (2.0f * Math.PI) / LOD;
|
||||
final double dt = 1.0 / LOD;
|
||||
gl.glBegin(GL.GL_TRIANGLE_STRIP);
|
||||
gl.glNormal3d(0, 0, 1);
|
||||
for (int i = 0; i < LOD + 1; i++) {
|
||||
gl.glTexCoord2d(i * dt, .875);
|
||||
gl.glVertex3d(r * Math.cos(da * i), r * Math.sin(da * i), 0);
|
||||
gl.glTexCoord2d(i * dt, 1);
|
||||
gl.glVertex3d(0, 0, 0);
|
||||
|
||||
}
|
||||
gl.glEnd();
|
||||
}
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import javax.media.opengl.GL2ES1;
|
||||
import javax.media.opengl.GLAutoDrawable;
|
||||
import javax.media.opengl.fixedfunc.GLLightingFunc;
|
||||
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
@ -16,6 +17,7 @@ import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
public class FigureRenderer extends RocketRenderer {
|
||||
private final float[] color = new float[4];
|
||||
@ -29,9 +31,9 @@ public class FigureRenderer extends RocketRenderer {
|
||||
|
||||
GL2 gl = drawable.getGL().getGL2();
|
||||
|
||||
gl.glLightModelfv(GL2ES1.GL_LIGHT_MODEL_AMBIENT,
|
||||
new float[] { 0,0,0 }, 0);
|
||||
|
||||
gl.glLightModelfv(GL2ES1.GL_LIGHT_MODEL_AMBIENT,
|
||||
new float[] { 0, 0, 0 }, 0);
|
||||
|
||||
float amb = 0.3f;
|
||||
float dif = 1.0f - amb;
|
||||
float spc = 1.0f;
|
||||
@ -41,21 +43,21 @@ public class FigureRenderer extends RocketRenderer {
|
||||
new float[] { dif, dif, dif, 1 }, 0);
|
||||
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR,
|
||||
new float[] { spc, spc, spc, 1 }, 0);
|
||||
|
||||
|
||||
gl.glEnable(GLLightingFunc.GL_LIGHT1);
|
||||
gl.glEnable(GLLightingFunc.GL_LIGHTING);
|
||||
gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
|
||||
|
||||
|
||||
gl.glEnable(GLLightingFunc.GL_NORMALIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDrawn(RocketComponent c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDrawnTransparent(RocketComponent c) {
|
||||
if (c instanceof BodyTube)
|
||||
@ -74,7 +76,7 @@ public class FigureRenderer extends RocketRenderer {
|
||||
}
|
||||
|
||||
private static final HashMap<Class<?>, Color> defaultColorCache = new HashMap<Class<?>, Color>();
|
||||
|
||||
|
||||
@Override
|
||||
public void renderComponent(GL2 gl, RocketComponent c, float alpha) {
|
||||
|
||||
@ -88,13 +90,13 @@ public class FigureRenderer extends RocketRenderer {
|
||||
defaultColorCache.put(c.getClass(), figureColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set up the front A&D color
|
||||
convertColor(figureColor, color);
|
||||
color[3] = alpha;
|
||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_DIFFUSE, color, 0);
|
||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, color, 0);
|
||||
|
||||
|
||||
// Set up the Specular color & Shine
|
||||
convertColor(figureColor, color);
|
||||
float d = 0.9f;
|
||||
@ -102,13 +104,13 @@ public class FigureRenderer extends RocketRenderer {
|
||||
color[0] = Math.max(color[0], d) * m;
|
||||
color[1] = Math.max(color[1], d) * m;
|
||||
color[2] = Math.max(color[2], d) * m;
|
||||
|
||||
|
||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_SPECULAR, color, 0);
|
||||
gl.glMateriali(GL.GL_FRONT, GLLightingFunc.GL_SHININESS, getShine(c));
|
||||
|
||||
color[0] = color[1] = color[2] = 0;
|
||||
gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_SPECULAR, color, 0);
|
||||
|
||||
|
||||
//Back A&D
|
||||
convertColor(figureColor, color);
|
||||
color[0] = color[0] * 0.4f;
|
||||
@ -117,7 +119,7 @@ public class FigureRenderer extends RocketRenderer {
|
||||
color[3] = alpha;
|
||||
gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_DIFFUSE, color, 0);
|
||||
gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_AMBIENT, color, 0);
|
||||
|
||||
|
||||
cr.renderGeometry(gl, c);
|
||||
}
|
||||
|
||||
@ -140,9 +142,9 @@ public class FigureRenderer extends RocketRenderer {
|
||||
}
|
||||
return 20;
|
||||
}
|
||||
|
||||
|
||||
protected static void convertColor(Color color, float[] out) {
|
||||
if ( color == null ){
|
||||
if (color == null) {
|
||||
out[0] = 1;
|
||||
out[1] = 1;
|
||||
out[2] = 0;
|
||||
@ -152,4 +154,13 @@ public class FigureRenderer extends RocketRenderer {
|
||||
out[2] = Math.max(0.2f, (float) color.getBlue() / 255f) * 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void renderMotor(GL2 gl, Coordinate c, Motor motor) {
|
||||
final float outside[] = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_DIFFUSE, outside, 0);
|
||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, outside, 0);
|
||||
super.renderMotor(gl, c, motor);
|
||||
}
|
||||
}
|
||||
|
@ -14,9 +14,12 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc;
|
||||
|
||||
import net.sf.openrocket.appearance.Appearance;
|
||||
import net.sf.openrocket.appearance.Decal;
|
||||
import net.sf.openrocket.appearance.defaults.MotorAppearance;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.util.Color;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
|
||||
import com.jogamp.opengl.util.texture.Texture;
|
||||
import com.jogamp.opengl.util.texture.TextureData;
|
||||
@ -92,8 +95,26 @@ public class RealisticRenderer extends RocketRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderComponent(GL2 gl, RocketComponent c, float alpha) {
|
||||
final Appearance a = getAppearance(c);
|
||||
protected void renderMotor(final GL2 gl, final Coordinate c, final Motor motor) {
|
||||
render(gl, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cr.renderMotor(gl, c, motor);
|
||||
}
|
||||
}, MotorAppearance.getAppearance(motor), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderComponent(final GL2 gl, final RocketComponent c, final float alpha) {
|
||||
render(gl, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cr.renderGeometry(gl, c);
|
||||
}
|
||||
}, getAppearance(c), alpha);
|
||||
}
|
||||
|
||||
private void render(GL2 gl, Runnable g, Appearance a, float alpha) {
|
||||
final Decal t = a.getTexture();
|
||||
final Texture tex = getTexture(t);
|
||||
|
||||
@ -116,7 +137,7 @@ public class RealisticRenderer extends RocketRenderer {
|
||||
gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_SPECULAR, colorBlack, 0);
|
||||
gl.glMateriali(GL.GL_BACK, GLLightingFunc.GL_SHININESS, 0);
|
||||
|
||||
cr.renderGeometry(gl, c);
|
||||
g.run();
|
||||
|
||||
if (t != null && tex != null) {
|
||||
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR);
|
||||
@ -155,7 +176,7 @@ public class RealisticRenderer extends RocketRenderer {
|
||||
gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotrophy);
|
||||
}
|
||||
|
||||
cr.renderGeometry(gl, c);
|
||||
g.run();
|
||||
|
||||
if (t.getEdgeMode() == Decal.EdgeMode.STICKER) {
|
||||
gl.glDepthFunc(GL.GL_LESS);
|
||||
|
@ -176,16 +176,19 @@ public abstract class RocketRenderer {
|
||||
MotorMount mount = iterator.next();
|
||||
Motor motor = mount.getMotor(motorID);
|
||||
double length = motor.getLength();
|
||||
double radius = motor.getDiameter() / 2;
|
||||
|
||||
Coordinate[] position = ((RocketComponent) mount).toAbsolute(new Coordinate(((RocketComponent) mount)
|
||||
.getLength() + mount.getMotorOverhang() - length));
|
||||
|
||||
for (int i = 0; i < position.length; i++) {
|
||||
cr.renderMotor(gl, position[i], length, radius);
|
||||
renderMotor(gl, position[i], motor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void renderMotor(GL2 gl, Coordinate c, Motor motor) {
|
||||
cr.renderMotor(gl, c, motor);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user