$search
00001 /******************************************************************************* 00002 * Copyright (c) 2012 Stefan Profanter. All rights reserved. This program and the accompanying 00003 * materials are made available under the terms of the GNU Public License v3.0 which accompanies 00004 * this distribution, and is available at http://www.gnu.org/licenses/gpl.html 00005 * 00006 * Contributors: Stefan Profanter - initial API and implementation, Year: 2012 00007 ******************************************************************************/ 00008 package edu.tum.cs.vis.model.util; 00009 00010 import java.awt.Color; 00011 import java.awt.Image; 00012 import java.awt.image.BufferedImage; 00013 import java.io.File; 00014 import java.io.IOException; 00015 import java.io.Serializable; 00016 import java.util.ArrayList; 00017 import java.util.HashMap; 00018 import java.util.HashSet; 00019 00020 import javax.imageio.ImageIO; 00021 import javax.vecmath.Point3f; 00022 00023 import processing.core.PGraphics; 00024 import processing.core.PImage; 00025 import edu.tum.cs.ias.knowrob.utils.FileUtil; 00026 00036 public class Mesh implements Serializable { 00037 00041 private static final long serialVersionUID = -2761386921853967131L; 00042 00046 protected Float minX = null; 00050 protected Float maxX = null; 00054 protected Float minY = null; 00058 protected Float maxY = null; 00062 protected Float minZ = null; 00066 protected Float maxZ = null; 00071 private boolean texturesInitialized = false; 00072 00076 private String textureBasePath; 00080 private ArrayList<Triangle> triangles = new ArrayList<Triangle>(); 00081 00085 private ArrayList<Line> lines = new ArrayList<Line>(); 00086 00093 public void drawBoundingBox(PGraphics g) { 00094 if (triangles.size() == 0 && lines.size() == 0) 00095 return; 00096 // Save current translation 00097 g.pushMatrix(); 00098 g.translate(getMaxX() - getWidth() / 2f, getMaxY() - getHeight() / 2f, getMaxZ() 00099 - getDepth() / 2f); 00100 g.box(getWidth(), getHeight(), getDepth()); 00101 00102 // Restore last translation 00103 g.popMatrix(); 00104 } 00105 00115 public void drawLines(PGraphics g, Color overrideColor) { 00116 for (Line line : lines) { 00117 00118 line.draw(g, overrideColor); 00119 } 00120 } 00121 00131 public void drawTriangles(PGraphics g, Color overrideColor) { 00132 if (!texturesInitialized) 00133 setTextureImage(); 00134 synchronized (triangles) { 00135 for (Triangle tri : triangles) { 00136 tri.draw(g, overrideColor); 00137 } 00138 } 00139 } 00140 00147 public float getDepth() { 00148 if (minZ != null && maxZ != null) 00149 return Math.abs(maxZ - minZ); 00150 if (triangles.size() == 0) { 00151 minZ = 0f; 00152 maxZ = 0f; 00153 } else { 00154 minZ = Float.MAX_VALUE; 00155 maxZ = Float.MIN_VALUE; 00156 00157 for (Triangle tri : triangles) { 00158 for (int v = 0; v < 3; v++) { 00159 minZ = Math.min(tri.position[v].z, minZ); 00160 maxZ = Math.max(tri.position[v].z, maxZ); 00161 } 00162 } 00163 for (Line line : lines) { 00164 for (int v = 0; v < 2; v++) { 00165 minZ = Math.min(line.position[v].z, minZ); 00166 maxZ = Math.max(line.position[v].z, maxZ); 00167 } 00168 } 00169 } 00170 return maxZ - minZ; 00171 } 00172 00179 public float getHeight() { 00180 if (minY != null && maxY != null) 00181 return Math.abs(maxY - minY); 00182 if (triangles.size() == 0) { 00183 minY = 0f; 00184 maxY = 0f; 00185 } else { 00186 minY = Float.MAX_VALUE; 00187 maxY = Float.MIN_VALUE; 00188 00189 for (Triangle tri : triangles) { 00190 for (int v = 0; v < 3; v++) { 00191 minY = Math.min(tri.position[v].y, minY); 00192 maxY = Math.max(tri.position[v].y, maxY); 00193 } 00194 } 00195 for (Line line : lines) { 00196 for (int v = 0; v < 2; v++) { 00197 minY = Math.min(line.position[v].y, minY); 00198 maxY = Math.max(line.position[v].y, maxY); 00199 } 00200 } 00201 } 00202 return maxY - minY; 00203 } 00204 00217 public void getIntersectedTriangles(final Point3f rayStart, final Point3f rayEnd, 00218 final ArrayList<IntersectedTriangle> intersectedTriangles) { 00219 00220 for (Triangle tri : triangles) { 00221 Point3f intersect = new Point3f(); 00222 if (tri.intersectsRay(rayStart, rayEnd, intersect)) 00223 intersectedTriangles.add(new IntersectedTriangle(tri, intersect)); 00224 } 00225 00226 } 00227 00233 public ArrayList<Line> getLines() { 00234 return lines; 00235 } 00236 00243 public Float getMaxX() { 00244 if (maxX == null) 00245 getWidth(); 00246 return maxX; 00247 } 00248 00255 public Float getMaxY() { 00256 if (maxY == null) 00257 getHeight(); 00258 return maxY; 00259 } 00260 00267 public Float getMaxZ() { 00268 if (maxZ == null) 00269 getDepth(); 00270 return maxZ; 00271 } 00272 00279 public Float getMinX() { 00280 if (minX == null) 00281 getWidth(); 00282 return minX; 00283 } 00284 00291 public Float getMinY() { 00292 if (minY == null) 00293 getHeight(); 00294 return minY; 00295 } 00296 00303 public Float getMinZ() { 00304 if (minZ == null) 00305 getDepth(); 00306 return minZ; 00307 } 00308 00314 public String getTextureBasePath() { 00315 return textureBasePath; 00316 } 00317 00323 public ArrayList<Triangle> getTriangles() { 00324 return triangles; 00325 } 00326 00333 public float getWidth() { 00334 if (minX != null && maxX != null) 00335 return Math.abs(maxX - minX); 00336 if (triangles.size() == 0) { 00337 minX = 0f; 00338 maxX = 0f; 00339 } else { 00340 minX = Float.MAX_VALUE; 00341 maxX = Float.MIN_VALUE; 00342 00343 for (Triangle tri : triangles) { 00344 for (int v = 0; v < 3; v++) { 00345 minX = Math.min(tri.position[v].x, minX); 00346 maxX = Math.max(tri.position[v].x, maxX); 00347 } 00348 } 00349 for (Line line : lines) { 00350 for (int v = 0; v < 2; v++) { 00351 minX = Math.min(line.position[v].x, minX); 00352 maxX = Math.max(line.position[v].x, maxX); 00353 } 00354 } 00355 } 00356 return maxX - minX; 00357 } 00358 00363 public void resetMinMaxValues() { 00364 minX = maxX = minY = maxY = minZ = maxZ = null; 00365 } 00366 00373 public void setLines(ArrayList<Line> lines) { 00374 this.lines = lines; 00375 } 00376 00383 public void setTextureBasePath(String textureBasePath) { 00384 this.textureBasePath = textureBasePath; 00385 } 00386 00392 private void setTextureImage() { 00393 if (textureBasePath == null) 00394 return; 00395 // load all Texture-Images only once (memory efficiency) 00396 HashMap<String, PImage> pictures = new HashMap<String, PImage>(); 00397 HashSet<String> alreadyLoaded = new HashSet<String>();// if error reading file, 00398 // pictures<path> is null. So avoid 00399 // trying again 00400 for (Triangle tri : triangles) { 00401 if (tri.appearance.getImageFileName() == null) 00402 continue; 00403 String texfile = FileUtil.getAbsoluteFilePath(textureBasePath, 00404 tri.appearance.getImageFileName()); 00405 if (pictures.get(texfile) == null && !alreadyLoaded.contains(texfile)) { 00406 00407 alreadyLoaded.add(texfile); 00408 BufferedImage bimg = null; 00409 try { 00410 bimg = ImageIO.read(new File(texfile)); 00411 // Convert BufferedImage to Image otherwise PImage constructor will fail!! 00412 00413 Image i = bimg.getScaledInstance(bimg.getWidth(), bimg.getHeight(), 0); 00414 00415 PImage pImg = new PImage(i); 00416 00417 pictures.put(texfile, pImg); 00418 } catch (IOException e) { 00419 System.err.println("Couldn't read file: " + texfile); 00420 } 00421 00422 } 00423 } 00424 00425 // Now remove offset of texture coordinates because there is a bug with P3D when texture 00426 // should repeated 00427 for (Triangle tri : triangles) { 00428 00429 if (tri.appearance.getImageFileName() == null) 00430 continue; 00431 00432 String texfile = FileUtil.getAbsoluteFilePath(textureBasePath, 00433 tri.appearance.getImageFileName()); 00434 // PImage tex = applet.loadImage(texfile); 00435 PImage tex = pictures.get(texfile); 00436 if (tex == null) 00437 continue; 00438 00439 double xMin = Double.MAX_VALUE; 00440 double yMin = Double.MAX_VALUE; 00441 00442 for (int i = 0; i < 3; i++) { 00443 00444 double x = tri.texPosition[i].x * tex.width; 00445 double y = tex.height - tri.texPosition[i].y * tex.height; 00446 tri.texPosition[i].x = (float) x; 00447 tri.texPosition[i].y = (float) y; 00448 xMin = Math.min(x, xMin); 00449 yMin = Math.min(y, yMin); 00450 } 00451 00452 // Remove offset of texture coordinate if all coordinates are greater than texture 00453 xMin = Math.floor(xMin / tex.width); 00454 yMin = Math.floor(yMin / tex.height); 00455 00456 for (int i = 0; i < 3; i++) { 00457 tri.texPosition[i].x -= xMin * tex.width; 00458 tri.texPosition[i].y -= yMin * tex.height; 00459 } 00460 00461 tri.appearance.setImageReference(tex); 00462 } 00463 texturesInitialized = true; 00464 } 00465 00472 public void setTriangles(ArrayList<Triangle> triangles) { 00473 this.triangles = triangles; 00474 } 00475 00476 }