~ubuntu-branches/ubuntu/utopic/sweethome3d/utopic-proposed

« back to all changes in this revision

Viewing changes to src/com/eteks/sweethome3d/j3d/Object3DBranch.java

  • Committer: Package Import Robot
  • Author(s): Gabriele Giacone
  • Date: 2014-01-28 02:27:55 UTC
  • mfrom: (1.1.15)
  • Revision ID: package-import@ubuntu.com-20140128022755-by8zvvmhwiju905v
Tags: 4.3+dfsg-1
* New upstream release.
* Bump Standards-Version to 3.9.5 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
import java.util.HashMap;
30
30
import java.util.List;
31
31
import java.util.Map;
 
32
import java.util.WeakHashMap;
32
33
 
33
34
import javax.media.j3d.BranchGroup;
34
35
import javax.media.j3d.ColoringAttributes;
35
36
import javax.media.j3d.LineAttributes;
36
37
import javax.media.j3d.Material;
37
38
import javax.media.j3d.PolygonAttributes;
 
39
import javax.media.j3d.Texture;
38
40
import javax.vecmath.Color3f;
39
41
 
 
42
import com.eteks.sweethome3d.model.Home;
40
43
import com.eteks.sweethome3d.model.Room;
41
44
 
42
45
/**
55
58
  protected static final Integer  DEFAULT_AMBIENT_COLOR = 0x333333;
56
59
  protected static final Material DEFAULT_MATERIAL      = new Material();
57
60
 
58
 
  private static final Map<Long, Material> materials = new HashMap<Long, Material>();
 
61
  private static final Map<Long, Material>              materials = new HashMap<Long, Material>();
 
62
  private static final Map<Home, Map<Texture, Texture>> homesTextures = new WeakHashMap<Home, Map<Texture, Texture>>();
59
63
  
60
64
  static {
61
65
    DEFAULT_MATERIAL.setCapability(Material.ALLOW_COMPONENT_READ);
69
73
  public abstract void update();
70
74
 
71
75
  /**
 
76
   * Returns a cloned instance of texture shared per <code>home</code> or 
 
77
   * the texture itself if <code>home</code> is <code>null</code>.
 
78
   * As sharing textures across universes might cause some problems, 
 
79
   * it's safer to handle a copy of textures for a given home. 
 
80
   */
 
81
  protected Texture getHomeTextureClone(Texture texture, Home home) {
 
82
    if (home == null || texture == null) {
 
83
      return texture;
 
84
    } else {
 
85
      Map<Texture, Texture> homeTextures = homesTextures.get(home);
 
86
      if (homeTextures == null) {
 
87
        homeTextures = new WeakHashMap<Texture, Texture>();
 
88
        homesTextures.put(home, homeTextures);
 
89
      }
 
90
      Texture clonedTexture = homeTextures.get(texture);
 
91
      if (clonedTexture == null) {
 
92
        clonedTexture = (Texture)texture.cloneNodeComponent(false);
 
93
        homeTextures.put(texture, clonedTexture);
 
94
      }
 
95
      return clonedTexture;
 
96
    }
 
97
  }
 
98
  
 
99
  /**
72
100
   * Returns the shape matching the coordinates in <code>points</code> array.
73
101
   */
74
102
  protected Shape getShape(float [][] points) {
195
223
        areaHoles.clear();
196
224
      }
197
225
    } else {
 
226
      List<Area> subAreas = new ArrayList<Area>(areaPointsLists.size());
198
227
      for (List<float []> holePoints : areaHolesLists) {
199
 
        // Search the closest points in the current area and the hole part
200
 
        float minDistance = Float.MAX_VALUE;
201
 
        int holeClosestPointIndex = 0;
202
 
        int areaClosestPointIndex = 0;
203
 
        List<float []> closestAreaPartPoints = null;
204
 
        for (int i = 0; i < areaPointsLists.size() && minDistance > 0; i++) {
205
 
          List<float []> areaPartPoints = areaPointsLists.get(i);
206
 
          for (int j = 0; j < holePoints.size() && minDistance > 0; j++) {
207
 
            for (int k = 0; k < areaPartPoints.size() && minDistance > 0; k++) {
208
 
              float distance = (float)Point2D.distanceSq(holePoints.get(j) [0], holePoints.get(j) [1],
209
 
                  areaPartPoints.get(k) [0], areaPartPoints.get(k) [1]);
 
228
        List<float []> enclosingAreaPartPoints = null;
 
229
        if (areaPointsLists.size() == 1) {
 
230
          enclosingAreaPartPoints = areaPointsLists.get(0);
 
231
        } else {
 
232
          // Search the sub area that contains the current hole
 
233
          for (int i = 0; i < areaPointsLists.size() && enclosingAreaPartPoints == null; i++) {
 
234
            Area subArea;
 
235
            if (i >= subAreas.size()) {
 
236
              List<float []> areaPartPoints = areaPointsLists.get(i);
 
237
              subArea = new Area(getShape(areaPartPoints.toArray(new float [areaPartPoints.size()][])));
 
238
              subAreas.add(subArea);
 
239
            } else {
 
240
              subArea = subAreas.get(i);
 
241
            }
 
242
            if (subArea.contains(holePoints.get(0) [0], holePoints.get(0) [1])) {
 
243
              enclosingAreaPartPoints = areaPointsLists.get(i);
 
244
            }
 
245
          }
 
246
        }
 
247
        
 
248
        // In some very rare cases, ignore very small areas that were wrongly considered as holes
 
249
        if (enclosingAreaPartPoints != null) {
 
250
          // Search the closest points in the enclosing area and the hole part
 
251
          float minDistance = Float.MAX_VALUE;
 
252
          int holeClosestPointIndex = 0;
 
253
          int areaClosestPointIndex = 0;
 
254
          for (int i = 0; i < holePoints.size() && minDistance > 0; i++) {
 
255
            for (int j = 0; j < enclosingAreaPartPoints.size() && minDistance > 0; j++) {
 
256
              float distance = (float)Point2D.distanceSq(holePoints.get(i) [0], holePoints.get(i) [1],
 
257
                  enclosingAreaPartPoints.get(j) [0], enclosingAreaPartPoints.get(j) [1]);
210
258
              if (distance < minDistance) {
211
259
                minDistance = distance;
212
 
                holeClosestPointIndex = j;
213
 
                areaClosestPointIndex = k;
214
 
                closestAreaPartPoints = areaPartPoints;
 
260
                holeClosestPointIndex = i;
 
261
                areaClosestPointIndex = j;
215
262
              }
216
263
            }
217
264
          }
218
 
        }
219
 
        // Combine the areas at their closest points
220
 
        if (minDistance != 0) {
221
 
          closestAreaPartPoints.add(areaClosestPointIndex, closestAreaPartPoints.get(areaClosestPointIndex));
222
 
          closestAreaPartPoints.add(++areaClosestPointIndex, holePoints.get(holeClosestPointIndex));
223
 
        }
224
 
        List<float []> lastPartPoints = holePoints.subList(holeClosestPointIndex, holePoints.size());
225
 
        closestAreaPartPoints.addAll(areaClosestPointIndex, lastPartPoints);
226
 
        closestAreaPartPoints.addAll(areaClosestPointIndex + lastPartPoints.size(), holePoints.subList(0, holeClosestPointIndex));
 
265
          // Combine the areas at their closest points
 
266
          if (minDistance != 0) {
 
267
            enclosingAreaPartPoints.add(areaClosestPointIndex, enclosingAreaPartPoints.get(areaClosestPointIndex));
 
268
            enclosingAreaPartPoints.add(++areaClosestPointIndex, holePoints.get(holeClosestPointIndex));
 
269
          }
 
270
          List<float []> lastPartPoints = holePoints.subList(holeClosestPointIndex, holePoints.size());
 
271
          enclosingAreaPartPoints.addAll(areaClosestPointIndex, lastPartPoints);
 
272
          enclosingAreaPartPoints.addAll(areaClosestPointIndex + lastPartPoints.size(), holePoints.subList(0, holeClosestPointIndex));
 
273
        }
227
274
      }
228
275
      
229
276
      for (List<float []> pathPoints : areaPointsLists) {