1 /* 2 * $RCSfile: GeometryArrayRetained.java,v $ 3 * 4 * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Sun designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Sun in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 24 * CA 95054 USA or visit www.sun.com if you need additional information or 25 * have any questions. 26 * 27 * $Revision: 1.12 $ 28 * $Date: 2008/02/28 20:17:22 $ 29 * $State: Exp $ 30 */ 31 32 package javax.media.j3d; 33 34 import com.sun.j3d.internal.Distance; 35 import javax.vecmath.*; 36 import java.lang.Math; 37 import java.util.ArrayList; 38 import java.util.Set; 39 import java.util.HashSet; 40 import java.util.HashMap; 41 import java.util.Vector; 42 import java.util.Enumeration; 43 import com.sun.j3d.internal.ByteBufferWrapper; 44 import com.sun.j3d.internal.BufferWrapper; 45 import com.sun.j3d.internal.FloatBufferWrapper; 46 import com.sun.j3d.internal.DoubleBufferWrapper; 47 48 49 /** 50 * The GeometryArray object contains arrays of positional coordinates, 51 * colors, normals and/or texture coordinates that describe 52 * point, line, or surface geometry. It is extended to create 53 * the various primitive types (e.g., lines, triangle_strips, etc.) 54 */ 55 56 abstract class GeometryArrayRetained extends GeometryRetained{ 57 58 // XXXX: Memory footprint reduction. Should have separate object to 59 // to contain specific data such as a ByRef object for 60 // all ByRef related data. So that incases where no 61 // ByRef is needed, the ByRef object reference is 62 // set to null. Hence saving memory! 63 // Need object such as Texture, D3d and ByRef ... 64 // 65 66 67 // Contains a bitset indicating which components are present 68 int vertexFormat; 69 70 // Whether this geometry was ever rendered as transparent 71 int c4fAllocated = 0; 72 73 // Total Number of vertices 74 int vertexCount; 75 76 // number of vertices used in rendering 77 int validVertexCount; 78 79 // The vertex data in packed format 80 float vertexData[]; 81 82 // vertex data in packed format for each screen in multi-screen situation 83 // if alpha values of each vertex are to be updated 84 private float mvertexData[][]; 85 86 // 87 // The following offset/stride values are internally computed 88 // from the format 89 // 90 91 // Stride (in words) from one vertex to the next 92 int stride; 93 94 // Stride (in words) from one texture coordinate to the next 95 int texCoordStride; 96 97 // Offset (in words) within each vertex of the coordinate position 98 int coordinateOffset; 99 100 // Offset (in words) within each vertex of the normal 101 int normalOffset; 102 103 // Offset (in words) within each vertex of the color 104 int colorOffset; 105 106 // Offset (in words) within each vertex of the texture coordinate 107 int textureOffset; 108 109 // Offset (in words) within each vertex of each vertex attribute 110 int[] vertexAttrOffsets; 111 112 // Stride (size) of all vertex attributes 113 int vertexAttrStride; 114 115 // alpha value for transparency and texture blending 116 private float[] lastAlpha = new float[1]; 117 float lastScreenAlpha = -1; 118 119 int colorChanged = 0; 120 121 // byte to float scale factor 122 static final float ByteToFloatScale = 1.0f/255.0f; 123 124 // float to byte scale factor 125 static final float FloatToByteScale = 255.0f; 126 127 // Set flag indicating that we are in the updater. This flag 128 // can be used by the various setRef methods to inhibit any 129 // update messages 130 boolean inUpdater = false; 131 132 // Array List used for messages 133 ArrayList gaList = new ArrayList(1); 134 135 136 // Target threads to be notified when morph changes 137 static final int targetThreads = (J3dThread.UPDATE_RENDER | 138 J3dThread.UPDATE_GEOMETRY); 139 140 // used for byReference geometry 141 float[] floatRefCoords = null; 142 double[] doubleRefCoords = null; 143 Point3d[] p3dRefCoords = null; 144 Point3f[] p3fRefCoords = null; 145 146 // Used for NIO buffer geometry 147 J3DBuffer coordRefBuffer = null; 148 FloatBufferWrapper floatBufferRefCoords = null; 149 DoubleBufferWrapper doubleBufferRefCoords = null; 150 151 // Initial index to use for rendering 152 int initialCoordIndex = 0; 153 int initialColorIndex = 0; 154 int initialNormalIndex = 0; 155 int[] initialTexCoordIndex = null; 156 int[] initialVertexAttrIndex = null; 157 int initialVertexIndex = 0; 158 159 160 // used for byReference colors 161 float[] floatRefColors = null; 162 byte[] byteRefColors = null; 163 Color3f[] c3fRefColors = null; 164 Color4f[] c4fRefColors = null; 165 Color3b[] c3bRefColors = null; 166 Color4b[] c4bRefColors = null; 167 168 // Used for NIO buffer colors 169 J3DBuffer colorRefBuffer = null; 170 FloatBufferWrapper floatBufferRefColors = null; 171 ByteBufferWrapper byteBufferRefColors = null; 172 173 // flag to indicate if the "by reference" component is already set 174 int vertexType = 0; 175 static final int PF = 0x1; 176 static final int PD = 0x2; 177 static final int P3F = 0x4; 178 static final int P3D = 0x8; 179 static final int VERTEX_DEFINED = PF | PD | P3F | P3D; 180 181 static final int CF = 0x10; 182 static final int CUB = 0x20; 183 static final int C3F = 0x40; 184 static final int C4F = 0x80; 185 static final int C3UB = 0x100; 186 static final int C4UB = 0x200; 187 static final int COLOR_DEFINED = CF | CUB | C3F | C4F| C3UB | C4UB; 188 189 static final int NF = 0x400; 190 static final int N3F = 0x800; 191 static final int NORMAL_DEFINED = NF | N3F; 192 193 static final int TF = 0x1000; 194 static final int T2F = 0x2000; 195 static final int T3F = 0x4000; 196 static final int TEXCOORD_DEFINED = TF | T2F | T3F; 197 198 static final int AF = 0x8000; 199 static final int VATTR_DEFINED = AF; 200 201 // Flag word indicating the type of by-ref texCoord. We will copy this to 202 // the vertexType field only when the references for all texture coordinate 203 // sets are set to non-null values. 204 private int texCoordType = 0; 205 206 // Flag word indicating the type of by-ref vertex attr. We will copy this to 207 // the vertexType field only when the references for all vertex attrs 208 // are set to non-null values. 209 private int vertexAttrType = 0; 210 211 // flag for execute geometry array when by reference 212 static final int COORD_FLOAT = 0x01; 213 static final int COORD_DOUBLE = 0x02; 214 static final int COLOR_FLOAT = 0x04; 215 static final int COLOR_BYTE = 0x08; 216 static final int NORMAL_FLOAT = 0x10; 217 static final int TEXCOORD_FLOAT = 0x20; 218 static final int VATTR_FLOAT = 0x40; 219 220 221 // used by "by reference" normals 222 float[] floatRefNormals = null; 223 Vector3f[] v3fRefNormals = null; 224 225 // Used for NIO buffer normals 226 J3DBuffer normalRefBuffer = null; 227 FloatBufferWrapper floatBufferRefNormals = null; 228 229 // used for "by reference" vertex attrs 230 float[][] floatRefVertexAttrs = null; 231 232 // Used for NIO buffer vertex attrs 233 J3DBuffer[] vertexAttrsRefBuffer = null; 234 FloatBufferWrapper[] floatBufferRefVertexAttrs = null; 235 Object[] nioFloatBufferRefVertexAttrs = null; 236 237 // used by "by reference" tex coords 238 Object[] refTexCoords = null; 239 TexCoord2f[] t2fRefTexCoords = null; 240 TexCoord3f[] t3fRefTexCoords = null; 241 242 // Used for NIO buffer tex coords 243 Object[] refTexCoordsBuffer = null; 244 //FloatBufferWrapper[] floatBufferRefTexCoords = null; 245 246 247 // used by interleaved array 248 float[] interLeavedVertexData = null; 249 250 // used by interleaved NIO buffer 251 J3DBuffer interleavedVertexBuffer = null; 252 FloatBufferWrapper interleavedFloatBufferImpl = null; 253 254 // pointers used, when transparency is turned on 255 // or when its an object such as C3F, P3F etc .. 256 float[] mirrorFloatRefCoords = null; 257 double[] mirrorDoubleRefCoords = null; 258 float[] mirrorFloatRefNormals = null; 259 float[][] mirrorFloatRefVertexAttrs = null; 260 float[] mirrorFloatRefTexCoords = null; 261 Object[] mirrorRefTexCoords = null; 262 263 float[][] mirrorFloatRefColors = new float[1][]; 264 byte[][] mirrorUnsignedByteRefColors= new byte[1][]; 265 float[][] mirrorInterleavedColorPointer = null; 266 267 // boolean to determine if a mirror was allocated 268 int mirrorVertexAllocated = 0; 269 int mirrorColorAllocated = 0; 270 boolean mirrorNormalAllocated = false; 271 272 // Some dirty bits for GeometryArrays 273 static final int COORDINATE_CHANGED = 0x01; 274 static final int NORMAL_CHANGED = 0x02; 275 static final int COLOR_CHANGED = 0x04; 276 static final int TEXTURE_CHANGED = 0x08; 277 static final int BOUNDS_CHANGED = 0x10; 278 static final int INDEX_CHANGED = 0x20; 279 static final int STRIPCOUNT_CHANGED = 0x40; 280 static final int VATTR_CHANGED = 0x80; 281 static final int VERTEX_CHANGED = COORDINATE_CHANGED | 282 NORMAL_CHANGED | 283 COLOR_CHANGED | 284 TEXTURE_CHANGED | 285 VATTR_CHANGED; 286 287 static final int defaultTexCoordSetMap[] = {0}; 288 int texCoordSetCount = 0; 289 int [] texCoordSetMap = null; 290 291 // this array contains offset to the texCoord data for each 292 // texture unit. -1 means no corresponding texCoord data offset 293 int [] texCoordSetMapOffset = null; 294 295 // Vertex attribute information 296 int vertexAttrCount = 0; 297 int[] vertexAttrSizes = null; 298 299 300 // This point to a list of VertexBuffers in a Vector structure 301 // Each element correspond to a D3D context that create this VB. 302 // Note that this GeometryArray can be used by multiple ctx. 303 long pVertexBuffers = 0; 304 int dirtyFlag; 305 306 // each bit corresponds to a unique renderer if shared context 307 // or a unique canvas otherwise 308 int resourceCreationMask = 0x0; 309 310 // Fix for Issue 5 311 // 312 // Replace the per-canvas reference count with a per-RenderBin set 313 // of users. The per-RenderBin set of users of this display list 314 // is defined as a HashMap where: 315 // 316 // key = the RenderBin 317 // value = a set of RenderAtomListInfo objects using this 318 // geometry array for display list purposes 319 private HashMap dlistUsers = null; 320 321 // timestamp used to create display list. This is either 322 // one per renderer for useSharedCtx, or one per Canvas for non-shared 323 // ctx 324 private long[] timeStampPerDlist = new long[2]; 325 326 // Unique display list Id, if this geometry is shared 327 int dlistId = -1; 328 Integer dlistObj = null; 329 330 // A list of pre-defined bits to indicate which component 331 // in this Texture object changed. 332 // static final int DLIST_CREATE_CHANGED = 0x01; 333 static final int INIT_MIRROR_GEOMETRY = 0x02; 334 335 336 // A list of Universes that this Geometry is referenced in Morph from 337 ArrayList morphUniverseList = null; 338 339 // A list of ArrayLists which contain all the MorphRetained objects 340 // refering to this geometry. Each list corresponds to the universe 341 // above. 342 ArrayList morphUserLists = null; 343 344 // The following variables are only used in compile mode 345 346 // Offset of a geometry array into the merged array 347 int[] geoOffset; 348 349 // vertexcount of a geometry array in a merge array 350 int[] compileVcount; 351 352 boolean isCompiled = false; 353 354 boolean isShared = false; 355 356 IndexedGeometryArrayRetained cloneSourceArray = null; 357 358 static final double EPS = 1.0e-13; 359 freeD3DArray(boolean deleteVB)360 void freeD3DArray(boolean deleteVB) { 361 assert VirtualUniverse.mc.isD3D(); 362 Pipeline.getPipeline().freeD3DArray(this, deleteVB); 363 } 364 GeometryArrayRetained()365 GeometryArrayRetained() { 366 dirtyFlag = INDEX_CHANGED|VERTEX_CHANGED; 367 lastAlpha[0] = 1.0f; 368 } 369 370 setLive(boolean inBackgroundGroup, int refCount)371 void setLive(boolean inBackgroundGroup, int refCount) { 372 dirtyFlag = VERTEX_CHANGED|INDEX_CHANGED; 373 isEditable = !isWriteStatic(); 374 super.doSetLive(inBackgroundGroup, refCount); 375 super.markAsLive(); 376 // Send message to RenderingAttribute structure to obtain a dlistId 377 // System.err.println("Geometry - "+this+"refCount = "+this.refCount); 378 if (this.refCount > 1) { 379 // Send to rendering attribute structure, 380 /* 381 J3dMessage createMessage = new J3dMessage(); 382 createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES; 383 createMessage.type = J3dMessage.GEOMETRYARRAY_CHANGED; 384 createMessage.universe = null; 385 createMessage.args[0] = this; 386 createMessage.args[1]= new Integer(DLIST_CREATE_CHANGED); 387 VirtualUniverse.mc.processMessage(createMessage); 388 */ 389 isShared = true; 390 } // Clone geometry only for the first setLive 391 else { 392 // If geometry is indexed and use_index_coord is false, unindexify 393 // otherwise, set mirrorGeometry to null (from previous clearLive) 394 if (this instanceof IndexedGeometryArrayRetained) { 395 // Send to rendering attribute structure, 396 J3dMessage createMessage = new J3dMessage(); 397 createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES; 398 createMessage.type = J3dMessage.GEOMETRY_CHANGED; 399 createMessage.universe = null; 400 createMessage.args[0] = null; 401 createMessage.args[1]= this; 402 createMessage.args[2]= new Integer(INIT_MIRROR_GEOMETRY); 403 VirtualUniverse.mc.processMessage(createMessage); 404 } 405 } 406 407 } 408 clearLive(int refCount)409 void clearLive(int refCount) { 410 super.clearLive(refCount); 411 412 if (this.refCount <= 0) { 413 if (pVertexBuffers != 0) { 414 J3dMessage renderMessage = new J3dMessage(); 415 renderMessage.threads = J3dThread.RENDER_THREAD; 416 renderMessage.type = J3dMessage.RENDER_IMMEDIATE; 417 renderMessage.universe = null; 418 renderMessage.view = null; 419 renderMessage.args[0] = null; 420 renderMessage.args[1] = this; 421 // Any one renderer is fine since VB store the ctx 422 // where it is created. 423 Enumeration e = Screen3D.deviceRendererMap.elements(); 424 Renderer rdr = (Renderer) e.nextElement(); 425 rdr.rendererStructure.addMessage(renderMessage); 426 VirtualUniverse.mc.setWorkForRequestRenderer(); 427 } 428 isShared = false; 429 } 430 } 431 computeBoundingBox()432 void computeBoundingBox() { 433 434 // System.err.println("computeBoundingBox ...."); 435 436 if (boundsDirty && VirtualUniverse.mc.cacheAutoComputedBounds) { 437 for(ArrayList<Shape3DRetained> users : userLists) { 438 for(Shape3DRetained shape : users) 439 shape.dirtyBoundsCache(); 440 } 441 } 442 443 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 444 // by copy 445 computeBoundingBox(initialVertexIndex, vertexData); 446 447 } else if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { // USE_NIO_BUFFER 448 //System.err.println("vertexFormat & GeometryArray.USE_NIO_BUFFER"); 449 if((vertexFormat & GeometryArray.INTERLEAVED) != 0) { 450 computeBoundingBox(initialCoordIndex, interleavedFloatBufferImpl); 451 } else if((vertexType & PF) != 0) { 452 computeBoundingBox(floatBufferRefCoords); 453 } else if((vertexType & PD) != 0) { 454 computeBoundingBox(doubleBufferRefCoords); 455 } 456 457 } else if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { 458 //System.err.println("vertexFormat & GeometryArray.INTERLEAVED"); 459 computeBoundingBox(initialCoordIndex, interLeavedVertexData); 460 } else if ((vertexType & PF) != 0) { 461 //System.err.println("vertexType & PF"); 462 computeBoundingBox(floatRefCoords); 463 } else if ((vertexType & P3F) != 0) { 464 //System.err.println("vertexType & P3F"); 465 computeBoundingBox(p3fRefCoords); 466 } else if ((vertexType & P3D) != 0) { 467 //System.err.println("vertexType & P3D"); 468 computeBoundingBox(p3dRefCoords); 469 } else if ((vertexType & PD) != 0) { 470 //System.err.println("vertexType & PD"); 471 computeBoundingBox(doubleRefCoords); 472 } 473 474 } 475 476 477 // NullGeometry is true only for byRef case processCoordsChanged(boolean nullGeo)478 void processCoordsChanged(boolean nullGeo) { 479 480 /* 481 System.err.println("processCoordsChanged : nullGeo " + nullGeo); 482 System.err.println("Before :processCoordsChanged : geoBounds "); 483 System.err.println(geoBounds); 484 */ 485 if (nullGeo) { 486 synchronized(geoBounds) { 487 geoBounds.setLower(-1.0, -1.0, -1.0); 488 geoBounds.setUpper(1.0, 1.0, 1.0); 489 boundsDirty = false; 490 } 491 synchronized(centroid) { 492 recompCentroid = false; 493 this.centroid.set(geoBounds.getCenter()); 494 } 495 496 } 497 else { 498 // re-compute centroid if used 499 synchronized(centroid) { 500 recompCentroid = true; 501 } 502 503 synchronized(geoBounds) { 504 boundsDirty = true; 505 computeBoundingBox(); 506 } 507 508 /* 509 System.err.println("After :processCoordsChanged : geoBounds "); 510 System.err.println(geoBounds); 511 */ 512 } 513 } 514 515 computeBoundingBox(int vIndex, float[] vdata)516 void computeBoundingBox(int vIndex, float[] vdata) { 517 int i, offset; 518 double xmin, xmax, ymin, ymax, zmin, zmax; 519 520 521 //System.err.println("Before : computeBoundingBox : geoBounds "); 522 // System.err.println(geoBounds); 523 524 synchronized(geoBounds) { 525 526 // If autobounds compute is false then return 527 // It is possible that user call getBounds() before 528 // this Geometry add to live scene graph. 529 if ((computeGeoBounds == 0) && (refCount > 0)) { 530 return; 531 } 532 if (!boundsDirty) 533 return; 534 535 // Initial offset 536 offset = vIndex * stride+coordinateOffset; 537 // Compute the bounding box 538 xmin = xmax = vdata[offset]; 539 ymin = ymax = vdata[offset+1]; 540 zmin = zmax = vdata[offset+2]; 541 offset += stride; 542 for (i=1; i<validVertexCount; i++) { 543 if (vdata[offset] > xmax) 544 xmax = vdata[offset]; 545 if (vdata[offset] < xmin) 546 xmin = vdata[offset]; 547 548 if (vdata[offset+1] > ymax) 549 ymax = vdata[offset+1]; 550 if (vdata[offset+1] < ymin) 551 ymin = vdata[offset+1]; 552 553 if (vdata[offset+2] > zmax) 554 zmax = vdata[offset+2]; 555 if (vdata[offset+2] < zmin) 556 zmin = vdata[offset+2]; 557 558 offset += stride; 559 } 560 561 geoBounds.setUpper(xmax, ymax, zmax); 562 geoBounds.setLower(xmin, ymin, zmin); 563 boundsDirty = false; 564 } 565 /* 566 System.err.println("After : computeBoundingBox : geoBounds "); 567 System.err.println(geoBounds); 568 */ 569 } 570 571 // Compute boundingbox for interleaved nio buffer computeBoundingBox(int vIndex, FloatBufferWrapper vdata)572 void computeBoundingBox(int vIndex, FloatBufferWrapper vdata) { 573 int i, offset; 574 double xmin, xmax, ymin, ymax, zmin, zmax; 575 576 577 synchronized(geoBounds) { 578 // If autobounds compute is false then return 579 if ((computeGeoBounds == 0) && (refCount > 0)) { 580 return; 581 } 582 583 if (!boundsDirty) 584 return; 585 586 // Initial offset 587 offset = vIndex * stride+coordinateOffset; 588 // Compute the bounding box 589 xmin = xmax = vdata.get(offset); 590 ymin = ymax = vdata.get(offset+1); 591 zmin = zmax = vdata.get(offset+2); 592 offset += stride; 593 for (i=1; i<validVertexCount; i++) { 594 if (vdata.get(offset) > xmax) 595 xmax = vdata.get(offset); 596 if (vdata.get(offset) < xmin) 597 xmin = vdata.get(offset); 598 599 if (vdata.get(offset+1) > ymax) 600 ymax = vdata.get(offset+1); 601 if (vdata.get(offset+1) < ymin) 602 ymin = vdata.get(offset+1); 603 604 if (vdata.get(offset+2) > zmax) 605 zmax = vdata.get(offset+2); 606 if (vdata.get(offset+2) < zmin) 607 zmin = vdata.get(offset+2); 608 609 offset += stride; 610 } 611 612 geoBounds.setUpper(xmax, ymax, zmax); 613 geoBounds.setLower(xmin, ymin, zmin); 614 boundsDirty = false; 615 } 616 } 617 618 619 // compute bounding box for coord with noi buffer computeBoundingBox( DoubleBufferWrapper buffer)620 void computeBoundingBox( DoubleBufferWrapper buffer) { 621 int i, j, k, sIndex; 622 double xmin, xmax, ymin, ymax, zmin, zmax; 623 624 synchronized(geoBounds) { 625 // If autobounds compute is false then return 626 if ((computeGeoBounds == 0) && (refCount > 0)) { 627 return; 628 } 629 630 if (!boundsDirty) 631 return; 632 633 sIndex = initialCoordIndex; 634 int maxIndex = 3*validVertexCount; 635 636 // Compute the bounding box 637 xmin = xmax = buffer.get(sIndex++); 638 ymin = ymax = buffer.get(sIndex++); 639 zmin = zmax = buffer.get(sIndex++); 640 641 for (i=sIndex; i<maxIndex; i+=3) { 642 j = i + 1; 643 k = i + 2; 644 645 if (buffer.get(i) > xmax) 646 xmax = buffer.get(i); 647 if (buffer.get(i) < xmin) 648 xmin = buffer.get(i); 649 650 if (buffer.get(j) > ymax) 651 ymax = buffer.get(j); 652 if (buffer.get(j) < ymin) 653 ymin = buffer.get(j); 654 655 if (buffer.get(k) > zmax) 656 zmax = buffer.get(k); 657 if (buffer.get(k) < zmin) 658 zmin = buffer.get(k); 659 660 } 661 geoBounds.setUpper(xmax, ymax, zmax); 662 geoBounds.setLower(xmin, ymin, zmin); 663 boundsDirty = false; 664 } 665 } 666 667 // compute bounding box for coord with noi buffer computeBoundingBox( FloatBufferWrapper buffer)668 void computeBoundingBox( FloatBufferWrapper buffer) { 669 int i, j, k, sIndex; 670 double xmin, xmax, ymin, ymax, zmin, zmax; 671 672 673 synchronized(geoBounds) { 674 // If autobounds compute is false then return 675 if ((computeGeoBounds == 0) && (refCount > 0)) { 676 return; 677 } 678 679 if (!boundsDirty) 680 return; 681 682 683 sIndex = initialCoordIndex; 684 int maxIndex = 3*validVertexCount; 685 686 // Compute the bounding box 687 xmin = xmax = buffer.get(sIndex++); 688 ymin = ymax = buffer.get(sIndex++); 689 zmin = zmax = buffer.get(sIndex++); 690 691 for (i=sIndex; i<maxIndex; i+=3) { 692 j = i + 1; 693 k = i + 2; 694 695 if (buffer.get(i) > xmax) 696 xmax = buffer.get(i); 697 if (buffer.get(i) < xmin) 698 xmin = buffer.get(i); 699 700 if (buffer.get(j) > ymax) 701 ymax = buffer.get(j); 702 if (buffer.get(j) < ymin) 703 ymin = buffer.get(j); 704 705 if (buffer.get(k) > zmax) 706 zmax = buffer.get(k); 707 if (buffer.get(k) < zmin) 708 zmin = buffer.get(k); 709 710 } 711 geoBounds.setUpper(xmax, ymax, zmax); 712 geoBounds.setLower(xmin, ymin, zmin); 713 boundsDirty = false; 714 } 715 } 716 computeBoundingBox(float[] coords)717 void computeBoundingBox(float[] coords) { 718 // System.err.println("GeometryArrayRetained : computeBoundingBox(float[] coords)"); 719 int i, j, k, sIndex; 720 double xmin, xmax, ymin, ymax, zmin, zmax; 721 722 synchronized(geoBounds) { 723 // If autobounds compute is false then return 724 if ((computeGeoBounds == 0) && (refCount > 0)) { 725 return; 726 } 727 728 if (!boundsDirty) 729 return; 730 731 sIndex = initialCoordIndex; 732 int maxIndex = 3*validVertexCount; 733 734 // Compute the bounding box 735 xmin = xmax = coords[sIndex++]; 736 ymin = ymax = coords[sIndex++]; 737 zmin = zmax = coords[sIndex++]; 738 739 for (i=sIndex; i<maxIndex; i+=3) { 740 j = i + 1; 741 k = i + 2; 742 743 if (coords[i] > xmax) 744 xmax = coords[i]; 745 if (coords[i] < xmin) 746 xmin = coords[i]; 747 748 if (coords[j] > ymax) 749 ymax = coords[j]; 750 if (coords[j] < ymin) 751 ymin = coords[j]; 752 753 if (coords[k] > zmax) 754 zmax = coords[k]; 755 if (coords[k] < zmin) 756 zmin = coords[k]; 757 758 } 759 geoBounds.setUpper(xmax, ymax, zmax); 760 // System.err.println("max(" + xmax + ", " + ymax + ", " + zmax + ")"); 761 geoBounds.setLower(xmin, ymin, zmin); 762 // System.err.println("min(" + xmin + ", " + ymin + ", " + zmin + ")"); 763 764 boundsDirty = false; 765 } 766 767 } 768 computeBoundingBox(double[] coords)769 void computeBoundingBox(double[] coords) { 770 int i, j, k, sIndex; 771 double xmin, xmax, ymin, ymax, zmin, zmax; 772 773 synchronized(geoBounds) { 774 // If autobounds compute is false then return 775 if ((computeGeoBounds == 0) && (refCount > 0)) { 776 return; 777 } 778 779 if (!boundsDirty) 780 return; 781 782 783 sIndex = initialCoordIndex; 784 int maxIndex = 3*validVertexCount; 785 786 // Compute the bounding box 787 xmin = xmax = coords[sIndex++]; 788 ymin = ymax = coords[sIndex++]; 789 zmin = zmax = coords[sIndex++]; 790 791 for (i=sIndex; i<maxIndex; i+=3) { 792 j = i + 1; 793 k = i + 2; 794 795 if (coords[i] > xmax) 796 xmax = coords[i]; 797 if (coords[i] < xmin) 798 xmin = coords[i]; 799 800 if (coords[j] > ymax) 801 ymax = coords[j]; 802 if (coords[j] < ymin) 803 ymin = coords[j]; 804 805 if (coords[k] > zmax) 806 zmax = coords[k]; 807 if (coords[k] < zmin) 808 zmin = coords[k]; 809 810 } 811 geoBounds.setUpper(xmax, ymax, zmax); 812 geoBounds.setLower(xmin, ymin, zmin); 813 boundsDirty = false; 814 } 815 816 } 817 computeBoundingBox(Point3f[] coords)818 void computeBoundingBox(Point3f[] coords) { 819 820 double xmin, xmax, ymin, ymax, zmin, zmax; 821 Point3f p; 822 823 synchronized(geoBounds) { 824 // If autobounds compute is false then return 825 if ((computeGeoBounds == 0) && (refCount > 0)) { 826 return; 827 } 828 829 if (!boundsDirty) 830 return; 831 832 833 834 // Compute the bounding box 835 xmin = xmax = coords[initialCoordIndex].x; 836 ymin = ymax = coords[initialCoordIndex].y; 837 zmin = zmax = coords[initialCoordIndex].z; 838 839 for (int i=initialCoordIndex+1; i<validVertexCount; i++) { 840 p = coords[i]; 841 if (p.x > xmax) xmax = p.x; 842 if (p.x < xmin) xmin = p.x; 843 844 if (p.y > ymax) ymax = p.y; 845 if (p.y < ymin) ymin = p.y; 846 847 if (p.z > zmax) zmax = p.z; 848 if (p.z < zmin) zmin = p.z; 849 850 } 851 geoBounds.setUpper(xmax, ymax, zmax); 852 geoBounds.setLower(xmin, ymin, zmin); 853 boundsDirty = false; 854 } 855 856 } 857 computeBoundingBox(Point3d[] coords)858 void computeBoundingBox(Point3d[] coords) { 859 860 double xmin, xmax, ymin, ymax, zmin, zmax; 861 Point3d p; 862 863 synchronized(geoBounds) { 864 // If autobounds compute is false then return 865 if ((computeGeoBounds == 0) && (refCount > 0)) { 866 return; 867 } 868 869 if (!boundsDirty) 870 return; 871 872 873 // Compute the bounding box 874 xmin = xmax = coords[initialCoordIndex].x; 875 ymin = ymax = coords[initialCoordIndex].y; 876 zmin = zmax = coords[initialCoordIndex].z; 877 878 for (int i=initialCoordIndex+1; i<validVertexCount; i++) { 879 p = coords[i]; 880 if (p.x > xmax) xmax = p.x; 881 if (p.x < xmin) xmin = p.x; 882 883 if (p.y > ymax) ymax = p.y; 884 if (p.y < ymin) ymin = p.y; 885 886 if (p.z > zmax) zmax = p.z; 887 if (p.z < zmin) zmin = p.z; 888 889 } 890 geoBounds.setUpper(xmax, ymax, zmax); 891 geoBounds.setLower(xmin, ymin, zmin); 892 boundsDirty = false; 893 } 894 895 } 896 897 update()898 synchronized void update() { 899 } 900 setupMirrorVertexPointer(int vType)901 void setupMirrorVertexPointer(int vType) { 902 int i, index; 903 904 switch (vType) { 905 case PF: 906 if (floatRefCoords == null) { 907 if ((vertexType & VERTEX_DEFINED) == PF) { 908 vertexType &= ~PF; 909 mirrorFloatRefCoords = null; 910 mirrorVertexAllocated &= ~PF; 911 } 912 } 913 else { 914 vertexType |= PF; 915 mirrorFloatRefCoords = floatRefCoords; 916 mirrorVertexAllocated &= ~PF; 917 } 918 919 break; 920 case PD: 921 if (doubleRefCoords == null) { 922 if ((vertexType & VERTEX_DEFINED) == PD) { 923 mirrorDoubleRefCoords = null; 924 mirrorVertexAllocated &= ~PD; 925 vertexType &= ~PD; 926 } 927 vertexType &= ~PD; 928 } 929 else { 930 vertexType |= PD; 931 mirrorDoubleRefCoords = doubleRefCoords; 932 mirrorVertexAllocated &= ~PD; 933 } 934 935 break; 936 case P3F: 937 if (p3fRefCoords == null) { 938 vertexType &= ~P3F; 939 // Don't set the mirrorFloatRefCoords to null, 940 // may be able to re-use 941 // mirrorFloatRefCoords = null; 942 } 943 else { 944 vertexType |= P3F; 945 946 if ((mirrorVertexAllocated & PF) == 0) { 947 mirrorFloatRefCoords = new float[vertexCount * 3]; 948 mirrorVertexAllocated |= PF; 949 } 950 951 index = initialCoordIndex * 3; 952 for ( i=initialCoordIndex; i<validVertexCount; i++) { 953 mirrorFloatRefCoords[index++] = p3fRefCoords[i].x; 954 mirrorFloatRefCoords[index++] = p3fRefCoords[i].y; 955 mirrorFloatRefCoords[index++] = p3fRefCoords[i].z; 956 } 957 } 958 break; 959 case P3D: 960 if (p3dRefCoords == null) { 961 vertexType &= ~P3D; 962 // Don't set the mirrorDoubleRefCoords to null, 963 // may be able to re-use 964 // mirrorDoubleRefCoords = null; 965 } 966 else { 967 vertexType |= P3D; 968 969 if ((mirrorVertexAllocated & PD) == 0) { 970 mirrorDoubleRefCoords = new double[vertexCount * 3]; 971 mirrorVertexAllocated |= PD; 972 } 973 974 index = initialCoordIndex * 3; 975 for ( i=initialCoordIndex; i<validVertexCount; i++) { 976 mirrorDoubleRefCoords[index++] = p3dRefCoords[i].x; 977 mirrorDoubleRefCoords[index++] = p3dRefCoords[i].y; 978 mirrorDoubleRefCoords[index++] = p3dRefCoords[i].z; 979 } 980 } 981 break; 982 default: 983 break; 984 985 } 986 987 } 988 989 // If turned transparent the first time, then force it to allocate setupMirrorInterleavedColorPointer(boolean force)990 void setupMirrorInterleavedColorPointer(boolean force) { 991 int index, length, offset; 992 int i; 993 994 if (force || (c4fAllocated != 0)) { // Color is present 995 996 length = 4 * vertexCount; 997 998 if (mirrorInterleavedColorPointer == null) { 999 mirrorInterleavedColorPointer = new float[1][length]; 1000 } 1001 1002 index = 4 * initialVertexIndex; 1003 offset = stride * initialVertexIndex + colorOffset; 1004 1005 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0 && 1006 interLeavedVertexData != null ) { // java array 1007 if ((vertexFormat & GeometryArray.WITH_ALPHA) != 0) { 1008 1009 for (i = initialVertexIndex; i < validVertexCount; i++) { 1010 mirrorInterleavedColorPointer[0][index++] = 1011 interLeavedVertexData[offset]; 1012 mirrorInterleavedColorPointer[0][index++] = 1013 interLeavedVertexData[offset+1]; 1014 mirrorInterleavedColorPointer[0][index++] = 1015 interLeavedVertexData[offset+2]; 1016 mirrorInterleavedColorPointer[0][index++] = 1017 interLeavedVertexData[offset+3]; 1018 offset += stride; 1019 } 1020 } 1021 else { 1022 for (i = initialVertexIndex; i < validVertexCount; i++) { 1023 mirrorInterleavedColorPointer[0][index++] = 1024 interLeavedVertexData[offset]; 1025 mirrorInterleavedColorPointer[0][index++] = 1026 interLeavedVertexData[offset+1]; 1027 mirrorInterleavedColorPointer[0][index++] = 1028 interLeavedVertexData[offset+2]; 1029 mirrorInterleavedColorPointer[0][index++] = 1.0f; 1030 offset += stride; 1031 } 1032 } 1033 1034 } else { // NIO BUFFER 1035 if ((vertexFormat & GeometryArray.WITH_ALPHA) != 0 && 1036 interleavedFloatBufferImpl != null) { 1037 for (i = initialVertexIndex; i < validVertexCount; i++) { 1038 interleavedFloatBufferImpl.position(offset); 1039 interleavedFloatBufferImpl.get(mirrorInterleavedColorPointer[0], 1040 index , 4); 1041 index += 4; 1042 offset += stride; 1043 } 1044 } 1045 else { 1046 for (i = initialVertexIndex; i < validVertexCount; i++) { 1047 interleavedFloatBufferImpl.position(offset); 1048 interleavedFloatBufferImpl.get(mirrorInterleavedColorPointer[0], 1049 index, 3); 1050 mirrorInterleavedColorPointer[0][index+3] = 1.0f; 1051 index += 4; 1052 offset += stride; 1053 1054 } 1055 } 1056 } 1057 c4fAllocated = GeometryArray.WITH_ALPHA; 1058 } 1059 } 1060 1061 // If turned transparent the first time, then force it to allocate setupMirrorColorPointer(int ctype, boolean force)1062 void setupMirrorColorPointer(int ctype, boolean force) { 1063 int i, srcIndex = 0, dstIndex = 0; 1064 int multiplier; 1065 1066 if (c4fAllocated == 0 && !force) { 1067 multiplier = 3; 1068 } else { 1069 1070 // If the first time, we are forced to allocate 4f, then 1071 // we need to force the allocation of the colors again 1072 // for the case when allocation has previously occurred 1073 // only for RGB 1074 if (force && (c4fAllocated == 0) && 1075 (vertexFormat & GeometryArray.WITH_ALPHA) == 0) { 1076 mirrorColorAllocated = 0; 1077 } 1078 c4fAllocated = GeometryArray.WITH_ALPHA; 1079 multiplier = 4; 1080 } 1081 1082 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { // java array 1083 switch (ctype) { 1084 case CF: 1085 if (floatRefColors == null) { 1086 if ((c4fAllocated == 0) && !force && 1087 (vertexType & COLOR_DEFINED) == CF) { 1088 mirrorFloatRefColors[0] = null; 1089 mirrorColorAllocated &= ~CF; 1090 } 1091 vertexType &= ~CF; 1092 return; 1093 } 1094 1095 vertexType |= CF; 1096 if (c4fAllocated == 0 && !force) { 1097 mirrorFloatRefColors[0] = floatRefColors; 1098 mirrorColorAllocated &= ~CF; 1099 } 1100 else { 1101 if ((mirrorColorAllocated & CF) == 0) { 1102 mirrorFloatRefColors[0] = new float[4 * vertexCount]; 1103 mirrorColorAllocated |= CF; 1104 } 1105 1106 if ((vertexFormat & GeometryArray.WITH_ALPHA) == 0) { 1107 1108 srcIndex = initialColorIndex * 3; 1109 dstIndex = initialColorIndex * 4; 1110 1111 for (i = initialColorIndex; i < validVertexCount; i++) { 1112 mirrorFloatRefColors[0][dstIndex++] = 1113 floatRefColors[srcIndex++]; 1114 mirrorFloatRefColors[0][dstIndex++] = 1115 floatRefColors[srcIndex++]; 1116 mirrorFloatRefColors[0][dstIndex++] = 1117 floatRefColors[srcIndex++]; 1118 mirrorFloatRefColors[0][dstIndex++] = 1.0f; 1119 } 1120 1121 } 1122 else { 1123 srcIndex = initialColorIndex * 4; 1124 System.arraycopy(floatRefColors, srcIndex, 1125 mirrorFloatRefColors[0], srcIndex, 1126 (4*validVertexCount)); 1127 } 1128 } 1129 break; 1130 case CUB: 1131 if (byteRefColors == null) { 1132 if (c4fAllocated == 0 && !force && 1133 ((vertexType & COLOR_DEFINED) == CUB) ) { 1134 mirrorUnsignedByteRefColors[0] = null; 1135 mirrorColorAllocated &= ~CUB; 1136 } 1137 vertexType &= ~CUB; 1138 return; 1139 } 1140 vertexType |= CUB; 1141 if (c4fAllocated == 0 && !force) { 1142 mirrorUnsignedByteRefColors[0] = byteRefColors; 1143 mirrorColorAllocated &= ~CUB;; 1144 } 1145 else { 1146 if ((mirrorColorAllocated & CUB) == 0) { 1147 mirrorUnsignedByteRefColors[0] = new byte[4 * vertexCount]; 1148 mirrorColorAllocated |= CUB; 1149 } 1150 if ((vertexFormat & GeometryArray.WITH_ALPHA) == 0) { 1151 1152 srcIndex = initialColorIndex * 3; 1153 dstIndex = initialColorIndex * 4; 1154 1155 for (i = initialColorIndex; i < validVertexCount; i++) { 1156 mirrorUnsignedByteRefColors[0][dstIndex++] = 1157 byteRefColors[srcIndex++]; 1158 mirrorUnsignedByteRefColors[0][dstIndex++] = 1159 byteRefColors[srcIndex++]; 1160 mirrorUnsignedByteRefColors[0][dstIndex++] = 1161 byteRefColors[srcIndex++]; 1162 mirrorUnsignedByteRefColors[0][dstIndex++] = 1163 (byte)(255.0); 1164 } 1165 } 1166 else { 1167 srcIndex = initialColorIndex * 4; 1168 System.arraycopy(byteRefColors, srcIndex, 1169 mirrorUnsignedByteRefColors[0], srcIndex, 1170 (4*validVertexCount)); 1171 } 1172 } 1173 1174 break; 1175 case C3F: 1176 if (c3fRefColors == null) { 1177 vertexType &= ~C3F; 1178 return; 1179 } 1180 vertexType |=C3F ; 1181 1182 if ((mirrorColorAllocated & CF) == 0) { 1183 mirrorFloatRefColors[0] = new float[vertexCount * multiplier]; 1184 mirrorColorAllocated |= CF; 1185 } 1186 if ((c4fAllocated & GeometryArray.WITH_ALPHA) == 0) { 1187 1188 dstIndex = initialColorIndex * 3; 1189 for (i = initialColorIndex; i < validVertexCount; i++) { 1190 mirrorFloatRefColors[0][dstIndex++] = c3fRefColors[i].x; 1191 mirrorFloatRefColors[0][dstIndex++] = c3fRefColors[i].y; 1192 mirrorFloatRefColors[0][dstIndex++] = c3fRefColors[i].z; 1193 } 1194 } else { 1195 1196 dstIndex = initialColorIndex * 4; 1197 for (i = initialColorIndex; i < validVertexCount; i++) { 1198 mirrorFloatRefColors[0][dstIndex++] = c3fRefColors[i].x; 1199 mirrorFloatRefColors[0][dstIndex++] = c3fRefColors[i].y; 1200 mirrorFloatRefColors[0][dstIndex++] = c3fRefColors[i].z; 1201 mirrorFloatRefColors[0][dstIndex++] = 1.0f; 1202 } 1203 } 1204 1205 break; 1206 case C4F: 1207 if (c4fRefColors == null) { 1208 vertexType &= ~C4F; 1209 return; 1210 } 1211 vertexType |=C4F ; 1212 1213 if ((mirrorColorAllocated & CF) == 0) { 1214 mirrorFloatRefColors[0] = new float[vertexCount << 2]; 1215 mirrorColorAllocated |= CF; 1216 } 1217 1218 dstIndex = initialColorIndex * 4; 1219 for (i = initialColorIndex; i < validVertexCount; i++) { 1220 mirrorFloatRefColors[0][dstIndex++] = c4fRefColors[i].x; 1221 mirrorFloatRefColors[0][dstIndex++] = c4fRefColors[i].y; 1222 mirrorFloatRefColors[0][dstIndex++] = c4fRefColors[i].z; 1223 mirrorFloatRefColors[0][dstIndex++] = c4fRefColors[i].w; 1224 } 1225 break; 1226 case C3UB: 1227 if (c3bRefColors == null) { 1228 vertexType &= ~C3UB; 1229 return; 1230 } 1231 vertexType |=C3UB ; 1232 1233 if ((mirrorColorAllocated & CUB) == 0) { 1234 mirrorUnsignedByteRefColors[0] = 1235 new byte[vertexCount * multiplier]; 1236 mirrorColorAllocated |= CUB; 1237 } 1238 if ((c4fAllocated & GeometryArray.WITH_ALPHA) == 0) { 1239 dstIndex = initialColorIndex * 3; 1240 for (i = initialColorIndex; i < validVertexCount; i++) { 1241 mirrorUnsignedByteRefColors[0][dstIndex++] = c3bRefColors[i].x; 1242 mirrorUnsignedByteRefColors[0][dstIndex++] = c3bRefColors[i].y; 1243 mirrorUnsignedByteRefColors[0][dstIndex++] = c3bRefColors[i].z; 1244 } 1245 } else { 1246 dstIndex = initialColorIndex * 4; 1247 for (i = initialColorIndex; i < validVertexCount; i++) { 1248 mirrorUnsignedByteRefColors[0][dstIndex++] = c3bRefColors[i].x; 1249 mirrorUnsignedByteRefColors[0][dstIndex++] = c3bRefColors[i].y; 1250 mirrorUnsignedByteRefColors[0][dstIndex++] = c3bRefColors[i].z; 1251 mirrorUnsignedByteRefColors[0][dstIndex++] = (byte)255; 1252 } 1253 } 1254 break; 1255 case C4UB: 1256 if (c4bRefColors == null) { 1257 vertexType &= ~C4UB; 1258 return; 1259 } 1260 vertexType |=C4UB ; 1261 if ((mirrorColorAllocated & CUB) == 0) { 1262 mirrorUnsignedByteRefColors[0] = new byte[vertexCount << 2]; 1263 mirrorColorAllocated |= CUB; 1264 } 1265 1266 dstIndex = initialColorIndex * 4; 1267 for (i = initialColorIndex; i < validVertexCount; i++) { 1268 mirrorUnsignedByteRefColors[0][dstIndex++] = c4bRefColors[i].x; 1269 mirrorUnsignedByteRefColors[0][dstIndex++] = c4bRefColors[i].y; 1270 mirrorUnsignedByteRefColors[0][dstIndex++] = c4bRefColors[i].z; 1271 mirrorUnsignedByteRefColors[0][dstIndex++] = c4bRefColors[i].w; 1272 } 1273 break; 1274 default: 1275 break; 1276 } 1277 } 1278 else { //USE_NIO_BUFFER is set 1279 if( colorRefBuffer == null) { 1280 if (c4fAllocated == 0 && !force && 1281 (vertexType & COLOR_DEFINED) == CF) { 1282 mirrorFloatRefColors[0] = null; 1283 mirrorColorAllocated &= ~CF; 1284 } 1285 vertexType &= ~CF; 1286 1287 if (c4fAllocated == 0 && !force && 1288 ((vertexType & COLOR_DEFINED) == CUB) ) { 1289 mirrorUnsignedByteRefColors[0] = null; 1290 mirrorColorAllocated &= ~CUB; 1291 } 1292 vertexType &= ~CUB; 1293 return; 1294 1295 } else if( floatBufferRefColors != null) { 1296 vertexType |= CF; 1297 vertexType &= ~CUB; 1298 if (c4fAllocated == 0 && !force) { 1299 // NOTE: make suren mirrorFloatRefColors[0] is set right 1300 mirrorFloatRefColors[0] = null; 1301 mirrorColorAllocated &= ~CF; 1302 } 1303 else { 1304 if ((mirrorColorAllocated & CF) == 0) { 1305 mirrorFloatRefColors[0] = new float[4 * vertexCount]; 1306 mirrorColorAllocated |= CF; 1307 } 1308 floatBufferRefColors.rewind(); 1309 if ((vertexFormat & GeometryArray.WITH_ALPHA) == 0) { 1310 srcIndex = initialColorIndex * 3; 1311 dstIndex = initialColorIndex * 4; 1312 floatBufferRefColors.position(srcIndex); 1313 1314 for (i = initialColorIndex; i < validVertexCount; i++) { 1315 floatBufferRefColors.get(mirrorFloatRefColors[0], dstIndex, 3); 1316 mirrorFloatRefColors[0][dstIndex+3] = 1.0f; 1317 dstIndex += 4; 1318 } 1319 } 1320 else { 1321 1322 srcIndex = initialColorIndex * 4; 1323 dstIndex = initialColorIndex * 4; 1324 floatBufferRefColors.position(srcIndex); 1325 for (i = initialColorIndex; i < validVertexCount; i++) { 1326 floatBufferRefColors.get(mirrorFloatRefColors[0], dstIndex, 4); 1327 dstIndex+= 4; 1328 } 1329 } 1330 } 1331 } else if ( byteBufferRefColors != null) { 1332 vertexType |= CUB; 1333 vertexType &= ~CF; 1334 if (c4fAllocated == 0 && !force) { 1335 // NOTE: make sure mirrorUnsignedByteRefColors[0] is set right 1336 mirrorUnsignedByteRefColors[0] = null; 1337 mirrorColorAllocated &= ~CUB;; 1338 } 1339 else { 1340 if ((mirrorColorAllocated & CUB) == 0) { 1341 mirrorUnsignedByteRefColors[0] = new byte[4 * vertexCount]; 1342 mirrorColorAllocated |= CUB; 1343 } 1344 1345 byteBufferRefColors.rewind(); 1346 if ((vertexFormat & GeometryArray.WITH_ALPHA) == 0) { 1347 srcIndex = initialColorIndex * 3; 1348 dstIndex = initialColorIndex * 4; 1349 byteBufferRefColors.position(srcIndex); 1350 for (i = initialColorIndex; i < validVertexCount; i++) { 1351 byteBufferRefColors.get(mirrorUnsignedByteRefColors[0], 1352 dstIndex, 3); 1353 mirrorUnsignedByteRefColors[0][dstIndex+3] = (byte)(255.0); 1354 dstIndex += 4; 1355 } 1356 } 1357 else { 1358 srcIndex = initialColorIndex * 4; 1359 dstIndex = initialColorIndex * 4; 1360 byteBufferRefColors.position(srcIndex); 1361 for (i = initialColorIndex; i < validVertexCount; i++) { 1362 byteBufferRefColors.get(mirrorUnsignedByteRefColors[0], dstIndex, 4); 1363 dstIndex+= 4; 1364 } 1365 } 1366 } // end of else 1367 }//end of else if ( byteBufferRefColors != null) 1368 }//end of NIO BUFFER case 1369 1370 colorChanged = 0xffff; 1371 } 1372 1373 setupMirrorNormalPointer(int ntype)1374 void setupMirrorNormalPointer(int ntype) { 1375 int i, index; 1376 1377 switch (ntype) { 1378 case NF: 1379 if (floatRefNormals == null) { 1380 if ((vertexType & NORMAL_DEFINED) == NF) { 1381 vertexType &= ~NF; 1382 mirrorFloatRefNormals = null; 1383 mirrorNormalAllocated = false; 1384 } 1385 } 1386 else { 1387 vertexType |= NF; 1388 mirrorFloatRefNormals = floatRefNormals; 1389 mirrorNormalAllocated = false; 1390 } 1391 break; 1392 case N3F: 1393 if (v3fRefNormals == null) { 1394 if ((vertexType & NORMAL_DEFINED) == N3F) { 1395 vertexType &= ~N3F; 1396 } 1397 return; 1398 } 1399 else { 1400 vertexType |= N3F; 1401 } 1402 if (!mirrorNormalAllocated) { 1403 mirrorFloatRefNormals = new float[vertexCount * 3]; 1404 mirrorNormalAllocated = true; 1405 } 1406 1407 index = initialNormalIndex * 3; 1408 for (i = initialNormalIndex; i < validVertexCount; i++) { 1409 mirrorFloatRefNormals[index++] = v3fRefNormals[i].x; 1410 mirrorFloatRefNormals[index++] = v3fRefNormals[i].y; 1411 mirrorFloatRefNormals[index++] = v3fRefNormals[i].z; 1412 } 1413 break; 1414 default: 1415 break; } 1416 } 1417 setupMirrorTexCoordPointer(int type)1418 void setupMirrorTexCoordPointer(int type) { 1419 for (int i = 0; i < texCoordSetCount; i++) { 1420 doSetupMirrorTexCoordPointer(i, type); 1421 } 1422 1423 validateTexCoordPointerType(); 1424 } 1425 setupMirrorTexCoordPointer(int texCoordSet, int type)1426 void setupMirrorTexCoordPointer(int texCoordSet, int type) { 1427 doSetupMirrorTexCoordPointer(texCoordSet, type); 1428 validateTexCoordPointerType(); 1429 } 1430 1431 // If all texCoord pointers are set to a non-null value, then set the 1432 // texcoord type in the vertexType flag word, else clear the texcoord type validateTexCoordPointerType()1433 private void validateTexCoordPointerType() { 1434 boolean allNonNull = true; 1435 boolean allNull = true; 1436 for (int i = 0; i < texCoordSetCount; i++) { 1437 if (refTexCoords[i] == null) { 1438 allNonNull = false; 1439 } else { 1440 allNull = false; 1441 } 1442 } 1443 1444 // Reset texCoordType if all references are null 1445 if (allNull) { 1446 texCoordType = 0; 1447 } 1448 1449 // Copy texCoordType to vertexType if all references are non-null 1450 vertexType &= ~TEXCOORD_DEFINED; 1451 if (allNonNull) { 1452 vertexType |= texCoordType; 1453 } 1454 } 1455 doSetupMirrorTexCoordPointer(int texCoordSet, int type)1456 private void doSetupMirrorTexCoordPointer(int texCoordSet, int type) { 1457 int i, index; 1458 1459 switch (type) { 1460 case TF: 1461 texCoordType = TF; 1462 mirrorRefTexCoords[texCoordSet] = refTexCoords[texCoordSet]; 1463 break; 1464 1465 case T2F: 1466 texCoordType = T2F; 1467 t2fRefTexCoords = (TexCoord2f[])refTexCoords[texCoordSet]; 1468 1469 if (t2fRefTexCoords == null) { 1470 mirrorRefTexCoords[texCoordSet] = null; 1471 break; 1472 } 1473 1474 mirrorFloatRefTexCoords = (float[])mirrorRefTexCoords[texCoordSet]; 1475 if (mirrorFloatRefTexCoords != null) { 1476 if (mirrorFloatRefTexCoords.length < (vertexCount * 2)) 1477 mirrorRefTexCoords[texCoordSet] = 1478 mirrorFloatRefTexCoords = new float[vertexCount * 2]; 1479 } 1480 else { 1481 mirrorRefTexCoords[texCoordSet] = 1482 mirrorFloatRefTexCoords = new float[vertexCount * 2]; 1483 } 1484 1485 index = initialTexCoordIndex[texCoordSet] * 2; 1486 for (i = initialTexCoordIndex[texCoordSet]; i < validVertexCount; i++) { 1487 mirrorFloatRefTexCoords[index++] = t2fRefTexCoords[i].x; 1488 mirrorFloatRefTexCoords[index++] = t2fRefTexCoords[i].y; 1489 } 1490 break; 1491 1492 case T3F: 1493 texCoordType = T3F; 1494 t3fRefTexCoords = (TexCoord3f[])refTexCoords[texCoordSet]; 1495 1496 if (t3fRefTexCoords == null) { 1497 mirrorRefTexCoords[texCoordSet] = null; 1498 break; 1499 } 1500 1501 mirrorFloatRefTexCoords = (float[])mirrorRefTexCoords[texCoordSet]; 1502 if (mirrorFloatRefTexCoords != null) { 1503 if (mirrorFloatRefTexCoords.length < (vertexCount * 3)) 1504 mirrorRefTexCoords[texCoordSet] = 1505 mirrorFloatRefTexCoords = new float[vertexCount * 3]; 1506 } 1507 else { 1508 mirrorRefTexCoords[texCoordSet] = 1509 mirrorFloatRefTexCoords = new float[vertexCount * 3]; 1510 } 1511 1512 index = initialTexCoordIndex[texCoordSet] * 3; 1513 for (i = initialTexCoordIndex[texCoordSet]; i < validVertexCount; i++) { 1514 mirrorFloatRefTexCoords[index++] = t3fRefTexCoords[i].x; 1515 mirrorFloatRefTexCoords[index++] = t3fRefTexCoords[i].y; 1516 mirrorFloatRefTexCoords[index++] = t3fRefTexCoords[i].z; 1517 } 1518 break; 1519 1520 default: 1521 break; 1522 } 1523 } 1524 setupMirrorVertexAttrPointer(int type)1525 void setupMirrorVertexAttrPointer(int type) { 1526 for (int i = 0; i < vertexAttrCount; i++) { 1527 doSetupMirrorVertexAttrPointer(i, type); 1528 } 1529 1530 validateVertexAttrPointerType(); 1531 } 1532 setupMirrorVertexAttrPointer(int vertexAttrNum, int type)1533 void setupMirrorVertexAttrPointer(int vertexAttrNum, int type) { 1534 doSetupMirrorVertexAttrPointer(vertexAttrNum, type); 1535 validateVertexAttrPointerType(); 1536 } 1537 1538 // If all vertex attr pointers are set to a non-null value, then set the 1539 // vertex attr type in the vertexType flag word, else clear the 1540 // vertex attr type validateVertexAttrPointerType()1541 private void validateVertexAttrPointerType() { 1542 boolean allNonNull = true; 1543 boolean allNull = true; 1544 1545 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 1546 for (int i = 0; i < vertexAttrCount; i++) { 1547 if (floatRefVertexAttrs[i] == null) { 1548 allNonNull = false; 1549 } else { 1550 allNull = false; 1551 } 1552 } 1553 } else { 1554 for (int i = 0; i < vertexAttrCount; i++) { 1555 if (nioFloatBufferRefVertexAttrs[i] == null) { 1556 allNonNull = false; 1557 } else { 1558 allNull = false; 1559 } 1560 } 1561 } 1562 1563 // Reset vertexAttrType if all references are null 1564 if (allNull) { 1565 vertexAttrType = 0; 1566 } 1567 1568 // Copy vertexAttrType to vertexType if all references are non-null 1569 vertexType &= ~VATTR_DEFINED; 1570 if (allNonNull) { 1571 vertexType |= vertexAttrType; 1572 } 1573 } 1574 doSetupMirrorVertexAttrPointer(int vertexAttrNum, int type)1575 private void doSetupMirrorVertexAttrPointer(int vertexAttrNum, int type) { 1576 switch (type) { 1577 case AF: 1578 vertexAttrType = AF; 1579 mirrorFloatRefVertexAttrs[vertexAttrNum] = 1580 floatRefVertexAttrs[vertexAttrNum]; 1581 break; 1582 default: 1583 break; 1584 } 1585 } 1586 1587 createGeometryArrayData(int vertexCount, int vertexFormat)1588 void createGeometryArrayData(int vertexCount, int vertexFormat) { 1589 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 1590 createGeometryArrayData(vertexCount, vertexFormat, 1, 1591 defaultTexCoordSetMap); 1592 } else { 1593 createGeometryArrayData(vertexCount, vertexFormat, 0, null); 1594 } 1595 } 1596 createGeometryArrayData(int vertexCount, int vertexFormat, int texCoordSetCount, int[] texCoordSetMap)1597 void createGeometryArrayData(int vertexCount, int vertexFormat, 1598 int texCoordSetCount, int[] texCoordSetMap) { 1599 1600 createGeometryArrayData(vertexCount, vertexFormat, 1601 texCoordSetCount, texCoordSetMap, 1602 0, null); 1603 } 1604 createGeometryArrayData(int vertexCount, int vertexFormat, int texCoordSetCount, int[] texCoordSetMap, int vertexAttrCount, int[] vertexAttrSizes)1605 void createGeometryArrayData(int vertexCount, int vertexFormat, 1606 int texCoordSetCount, int[] texCoordSetMap, 1607 int vertexAttrCount, int[] vertexAttrSizes) { 1608 this.vertexFormat = vertexFormat; 1609 this.vertexCount = vertexCount; 1610 this.validVertexCount = vertexCount; 1611 1612 this.texCoordSetCount = texCoordSetCount; 1613 if (texCoordSetMap == null) { 1614 this.texCoordSetMap = null; 1615 } 1616 else { 1617 this.texCoordSetMap = (int[])texCoordSetMap.clone(); 1618 } 1619 1620 this.vertexAttrCount = vertexAttrCount; 1621 if (vertexAttrSizes == null) { 1622 this.vertexAttrSizes = null; 1623 } 1624 else { 1625 this.vertexAttrSizes = (int[])vertexAttrSizes.clone(); 1626 } 1627 1628 this.vertexAttrStride = this.vertexAttrStride(); 1629 this.stride = this.stride(); 1630 1631 this.vertexAttrOffsets = this.vertexAttrOffsets(); 1632 this.texCoordSetMapOffset = this.texCoordSetMapOffset(); 1633 this.textureOffset = this.textureOffset(); 1634 this.colorOffset = this.colorOffset(); 1635 this.normalOffset = this.normalOffset(); 1636 this.coordinateOffset = this.coordinateOffset(); 1637 1638 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 1639 this.vertexData = new float[this.vertexCount * this.stride]; 1640 } 1641 else { // By reference geometry 1642 this.vertexData = null; 1643 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 1644 this.mirrorRefTexCoords = new Object[texCoordSetCount]; 1645 this.refTexCoords = new Object[texCoordSetCount]; // keep J3DBufferImp object in nio buffer case 1646 if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0 ) 1647 this.refTexCoordsBuffer = new Object[texCoordSetCount]; // keep J3DBuffer object 1648 } 1649 if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 1650 this.floatRefVertexAttrs = new float[vertexAttrCount][]; 1651 this.mirrorFloatRefVertexAttrs = new float[vertexAttrCount][]; 1652 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { 1653 this.vertexAttrsRefBuffer = new J3DBuffer[vertexAttrCount]; 1654 this.floatBufferRefVertexAttrs = new FloatBufferWrapper[vertexAttrCount]; 1655 this.nioFloatBufferRefVertexAttrs = new Object[vertexAttrCount]; 1656 } 1657 } 1658 } 1659 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 1660 this.initialTexCoordIndex = new int[texCoordSetCount]; 1661 } 1662 if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 1663 this.initialVertexAttrIndex = new int[vertexAttrCount]; 1664 } 1665 noAlpha = ((vertexFormat & GeometryArray.WITH_ALPHA) == 0); 1666 lastAlpha[0] = 1.0f; 1667 1668 } 1669 setVertexFormat(boolean useAlpha, boolean ignoreVC, Context ctx)1670 void setVertexFormat(boolean useAlpha, boolean ignoreVC, Context ctx) { 1671 Pipeline.getPipeline().setVertexFormat(ctx, 1672 this, vertexFormat, useAlpha, ignoreVC); 1673 } 1674 disableGlobalAlpha(Context ctx, boolean useAlpha, boolean ignoreVC)1675 void disableGlobalAlpha(Context ctx, boolean useAlpha, boolean ignoreVC) { 1676 // If global alpha was turned on, then disable it 1677 Pipeline.getPipeline().disableGlobalAlpha(ctx, 1678 this, vertexFormat, useAlpha, ignoreVC); 1679 } 1680 1681 updateAlphaInFloatRefColors(Canvas3D cv, int screen, float alpha)1682 float[] updateAlphaInFloatRefColors(Canvas3D cv, int screen, float alpha) { 1683 1684 //System.err.println("updateAlphaInFloatRefColors screen = " + screen + 1685 // " alpha " + alpha ); 1686 1687 // no need to update alpha values if canvas supports global alpha 1688 if (cv.supportGlobalAlpha()) { 1689 cv.setGlobalAlpha(cv.ctx, alpha); 1690 return mirrorFloatRefColors[0]; 1691 } 1692 1693 // update alpha only if vertex format includes alpha 1694 if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0) 1695 return mirrorFloatRefColors[0]; 1696 1697 // if alpha is smaller than EPSILON, set it to EPSILON, so that 1698 // even if alpha is equal to 0, we will not completely lose 1699 // the original alpha value 1700 if (alpha <= EPSILON) { 1701 alpha = (float)EPSILON; 1702 } 1703 1704 assert lastAlpha != null; 1705 assert mirrorFloatRefColors != null; 1706 assert mirrorFloatRefColors.length == lastAlpha.length; 1707 1708 // Issue 113 - reallocate lastAlpha array if needed, but no need to 1709 // update the values here 1710 if (lastAlpha.length <= screen) { 1711 float[] la = new float[screen + 1]; 1712 for (int i = 0; i < lastAlpha.length; i++) { 1713 la[i] = lastAlpha[i]; 1714 } 1715 lastAlpha = la; 1716 } 1717 1718 //System.err.println("updateAlphaInFloatRefColors screen is " + screen 1719 // + " mirrorFloatRefColors.length " + 1720 // mirrorFloatRefColors.length); 1721 1722 // allocate a copy of the color data for the screen if needed. 1723 // this piece of code is only for multi-screens case 1724 if (mirrorFloatRefColors.length <= screen) { 1725 float[][] cfData = new float[screen + 1][]; 1726 1727 for (int i = 0; i < mirrorFloatRefColors.length; i++) { 1728 cfData[i] = mirrorFloatRefColors[i]; 1729 } 1730 1731 // Issue 113 - allocate entries for [oldSize..screen]; 1732 // copy cfData[0] to cfData[oldsize..screen-1] and 1733 // lastAlpha[0] to lastAlpha[oldsize..screen-1]. 1734 for (int i = mirrorFloatRefColors.length; i < screen+1; i++) { 1735 cfData[i] = new float[4 * vertexCount]; 1736 System.arraycopy(cfData[0], 0, cfData[i], 0, 4 * vertexCount); 1737 lastAlpha[i] = lastAlpha[0]; 1738 } 1739 1740 mirrorFloatRefColors = cfData; 1741 1742 // Issue 113 - since we copied the data from screen 0, we don't need 1743 // to do any further special processing. 1744 } 1745 1746 assert lastAlpha[screen] >= 0.0; 1747 /* 1748 System.err.println("updateAlphaInFloatRefColors ** : lastAlpha[screen] " + 1749 lastAlpha[screen]); 1750 1751 System.err.println("((colorChanged & (1<<screen)) == 0) " + 1752 ((colorChanged & (1<<screen)) == 0)); 1753 */ 1754 1755 if ((colorChanged & (1<<screen)) == 0) { 1756 // color data is not modified 1757 if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) { 1758 // and if alpha is the same as the last one, 1759 // just return the data 1760 //System.err.println("updateAlphaInFloatRefColors 0 : alpha is the same as the last one " + alpha); 1761 1762 return mirrorFloatRefColors[screen]; 1763 } else { 1764 1765 // if alpha is different, update the alpha values 1766 //System.err.println("updateAlphaInFloatRefColors 1 : alpha is different, update the alpha values " + alpha); 1767 1768 float m = alpha / lastAlpha[screen]; 1769 1770 float[] cdata = mirrorFloatRefColors[screen]; 1771 1772 // We've to traverse the whole due to BugId : 4676483 1773 for (int i = 0, j = 0; i < vertexCount; i++, j+=4) { 1774 cdata[j+3] = cdata[j+3] * m; 1775 } 1776 } 1777 } else { 1778 // color data is modified 1779 if (screen == 0) { 1780 1781 // just update alpha values since screen 0 data is 1782 // already updated in setupMirrorColorPointer 1783 1784 //System.err.println("updateAlphaInFloatRefColors 2 : just update alpha = " + alpha); 1785 1786 float[] cdata = mirrorFloatRefColors[screen]; 1787 1788 1789 // This part is also incorrect due to BugId : 4676483 1790 // But traversing the whole array doesn't help either, as there 1791 // isn't a mechanism to indicate the the alpha component has 1792 // not changed by user. 1793 int j = initialColorIndex * 4; 1794 for (int i = initialColorIndex; i < validVertexCount; i++, j+=4) { 1795 cdata[j+3] = cdata[j+3] * alpha; 1796 } 1797 } else { 1798 // update color values from screen 0 data 1799 //System.err.println("updateAlphaInFloatRefColors 3 : update color values from screen 0 data " + alpha); 1800 1801 float m; 1802 1803 if ((colorChanged & 1) == 0) { 1804 // alpha is up to date in screen 0 1805 m = alpha / lastAlpha[0]; 1806 } else { 1807 m = alpha; 1808 } 1809 1810 float[] sdata = mirrorFloatRefColors[0]; 1811 float[] cdata = mirrorFloatRefColors[screen]; 1812 1813 int j = initialColorIndex * 4; 1814 for (int i = initialColorIndex; i < validVertexCount; i++) { 1815 cdata[j] = sdata[j++]; 1816 cdata[j] = sdata[j++]; 1817 cdata[j] = sdata[j++]; 1818 cdata[j] = sdata[j++] * m; 1819 } 1820 } 1821 } 1822 1823 lastAlpha[screen] = alpha; 1824 colorChanged &= ~(1 << screen); 1825 dirtyFlag |= COLOR_CHANGED; 1826 return mirrorFloatRefColors[screen]; 1827 } 1828 1829 updateAlphaInByteRefColors(Canvas3D cv, int screen, float alpha)1830 byte[] updateAlphaInByteRefColors(Canvas3D cv, int screen, float alpha) { 1831 1832 /* 1833 System.err.println("updateAlphaInByteRefColors screen = " + screen + 1834 " alpha " + alpha ); 1835 */ 1836 1837 // no need to update alpha values if canvas supports global alpha 1838 1839 if (cv.supportGlobalAlpha()) { 1840 cv.setGlobalAlpha(cv.ctx, alpha); 1841 return mirrorUnsignedByteRefColors[0]; 1842 } 1843 1844 // update alpha only if vertex format includes alpha 1845 if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0) 1846 return mirrorUnsignedByteRefColors[0]; 1847 1848 // if alpha is smaller than EPSILON, set it to EPSILON, so that 1849 // even if alpha is equal to 0, we will not completely lose 1850 // the original alpha value 1851 if (alpha <= EPSILON) { 1852 alpha = (float)EPSILON; 1853 } 1854 1855 assert lastAlpha != null; 1856 assert mirrorUnsignedByteRefColors != null; 1857 assert mirrorUnsignedByteRefColors.length == lastAlpha.length; 1858 1859 // Issue 113 - reallocate lastAlpha array if needed, but no need to 1860 // update the values here 1861 if (lastAlpha.length <= screen) { 1862 float[] la = new float[screen + 1]; 1863 for (int i = 0; i < lastAlpha.length; i++) { 1864 la[i] = lastAlpha[i]; 1865 } 1866 lastAlpha = la; 1867 } 1868 1869 // allocate a copy of the color data for the screen if needed. 1870 // this piece of code is only for multi-screens case 1871 if (mirrorUnsignedByteRefColors.length <= screen) { 1872 byte[][] cbData = new byte[screen + 1][]; 1873 for (int i = 0; i < mirrorUnsignedByteRefColors.length; i++) { 1874 cbData[i] = mirrorUnsignedByteRefColors[i]; 1875 } 1876 1877 // Issue 113 - allocate entries for [oldSize..screen]; 1878 // copy cbData[0] to cbData[oldsize..screen-1] and 1879 // lastAlpha[0] to lastAlpha[oldsize..screen-1]. 1880 for (int i = mirrorUnsignedByteRefColors.length; i < screen+1; i++) { 1881 cbData[i] = new byte[4 * vertexCount]; 1882 System.arraycopy(cbData[0], 0, cbData[i], 0, 4 * vertexCount); 1883 lastAlpha[i] = lastAlpha[0]; 1884 } 1885 1886 mirrorUnsignedByteRefColors = cbData; 1887 1888 // Issue 113 - since we copied the data from screen 0, we don't need 1889 // to do any further special processing. 1890 } 1891 1892 assert lastAlpha[screen] >= 0.0; 1893 /* 1894 System.err.println("updateAlphaInByteRefColors ## : lastAlpha[screen] " + 1895 lastAlpha[screen]); 1896 1897 System.err.println("((colorChanged & (1<<screen)) == 0) " + 1898 ((colorChanged & (1<<screen)) == 0)); 1899 */ 1900 1901 if ((colorChanged & (1<<screen)) == 0) { 1902 // color data is not modified 1903 if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) { 1904 // and if alpha is the same as the last one, 1905 // just return the data 1906 //System.err.println("updateAlphaInByteRefColors 0 : alpha is the same as the last one " + alpha); 1907 1908 return mirrorUnsignedByteRefColors[screen]; 1909 } else { 1910 // if alpha is different, update the alpha values 1911 1912 //System.err.println("updateAlphaInByteRefColors 1 : alpha is different, update the alpha values " + alpha); 1913 1914 float m = alpha / lastAlpha[screen]; 1915 1916 byte[] cdata = mirrorUnsignedByteRefColors[screen]; 1917 1918 // We've to traverse the whole due to BugId : 4676483 1919 for (int i = 0, j = 0; i < vertexCount; i++, j+=4) { 1920 cdata[j+3] = (byte)( ((int)cdata[j+3] & 0xff) * m); 1921 } 1922 } 1923 } else { 1924 // color data is modified 1925 if (screen == 0) { 1926 //System.err.println("updateAlphaInByteRefColors 2 : just update alpha =" + alpha); 1927 1928 // just update alpha values since screen 0 data is 1929 // already updated in setupMirrorColorPointer 1930 1931 byte[] cdata = mirrorUnsignedByteRefColors[screen]; 1932 1933 // This part is also incorrect due to BugId : 4676483 1934 // But traversing the whole array doesn't help either, as there 1935 // isn't a mechanism to indicate the the alpha component has 1936 // not changed by user. 1937 int j = initialColorIndex * 4; 1938 for (int i = initialColorIndex; i < validVertexCount; i++, j+=4) { 1939 cdata[j+3] = (byte)(((int)cdata[j+3] & 0xff) * alpha); 1940 } 1941 } else { 1942 // update color values from screen 0 data 1943 float m; 1944 1945 //System.err.println("updateAlphaInByteRefColors 3 : update color values from screen 0 data " + alpha); 1946 1947 if ((colorChanged & 1) == 0) { 1948 // alpha is up to date in screen 0 1949 m = alpha / lastAlpha[0]; 1950 } else { 1951 m = alpha; 1952 } 1953 byte[] sdata = mirrorUnsignedByteRefColors[0]; 1954 byte[] cdata = mirrorUnsignedByteRefColors[screen]; 1955 1956 int j = initialColorIndex * 4; 1957 for (int i = initialColorIndex; i < validVertexCount; i++) { 1958 cdata[j] = sdata[j++]; 1959 cdata[j] = sdata[j++]; 1960 cdata[j] = sdata[j++]; 1961 cdata[j] = (byte)(((int)sdata[j++]& 0xff) * m); 1962 } 1963 } 1964 } 1965 1966 lastAlpha[screen] = alpha; 1967 colorChanged &= ~(1 << screen); 1968 dirtyFlag |= COLOR_CHANGED; 1969 return mirrorUnsignedByteRefColors[screen]; 1970 } 1971 1972 updateAlphaInVertexData(Canvas3D cv, int screen, float alpha)1973 Object[] updateAlphaInVertexData(Canvas3D cv, int screen, float alpha) { 1974 1975 Object[] retVal = new Object[2]; 1976 retVal[0] = Boolean.FALSE; 1977 1978 // no need to update alpha values if canvas supports global alpha 1979 if (cv.supportGlobalAlpha()) { 1980 cv.setGlobalAlpha(cv.ctx, alpha); 1981 retVal[1] = vertexData; 1982 return retVal; 1983 } 1984 1985 // update alpha only if vertex format includes alpha 1986 if ((vertexFormat & GeometryArray.COLOR) == 0) { 1987 retVal[1] = vertexData; 1988 return retVal; 1989 } 1990 1991 // if alpha is smaller than EPSILON, set it to EPSILON, so that 1992 // even if alpha is equal to 0, we will not completely lose 1993 // the original alpha value 1994 if (alpha <= EPSILON) { 1995 alpha = (float)EPSILON; 1996 } 1997 retVal[0] = Boolean.TRUE; 1998 1999 assert lastAlpha != null; 2000 assert mvertexData == null || mvertexData.length == lastAlpha.length; 2001 2002 // Issue 113 - reallocate lastAlpha array if needed, but no need to 2003 // update the values here 2004 if (lastAlpha.length <= screen) { 2005 float[] la = new float[screen + 1]; 2006 for (int i = 0; i < lastAlpha.length; i++) { 2007 la[i] = lastAlpha[i]; 2008 } 2009 lastAlpha = la; 2010 } 2011 2012 // allocate a copy of the vertex data for the screen if needed. 2013 // Note that a copy operation only happens in the multi-screens case. 2014 // We always use the existing vertexData for screen 0. 2015 if (mvertexData == null || mvertexData.length <= screen) { 2016 2017 float[][] cfData = new float[screen + 1][]; 2018 int oldSize = 1; 2019 2020 if (mvertexData != null) { 2021 oldSize = mvertexData.length; 2022 for (int i = 0; i < mvertexData.length; i++) { 2023 cfData[i] = mvertexData[i]; 2024 } 2025 } 2026 2027 if (cfData[0] == null) { 2028 cfData[0] = vertexData; 2029 } 2030 2031 // Issue 113 - allocate entries for [oldSize..screen]; 2032 // copy cfData[0] to cfData[oldsize..screen-1] and 2033 // lastAlpha[0] to lastAlpha[oldsize..screen-1]. 2034 if (screen > 0) { 2035 for (int i = oldSize; i < screen+1; i++) { 2036 cfData[i] = new float[stride * vertexCount]; 2037 System.arraycopy(cfData[0], 0, cfData[i], 0, 2038 stride * vertexCount); 2039 lastAlpha[i] = lastAlpha[0]; 2040 } 2041 } 2042 2043 mvertexData = cfData; 2044 2045 // Issue 113 - since we copied the data from screen 0, we don't need 2046 // to do any further special processing. 2047 } 2048 2049 assert lastAlpha[screen] >= 0.0; 2050 2051 if ((colorChanged & (1<<screen)) == 0) { 2052 // color data is not modified 2053 if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) { 2054 // and if alpha is the same as the last one, 2055 // just return the data 2056 retVal[1] = mvertexData[screen]; 2057 return retVal; 2058 } else { 2059 // if alpha is different, update the alpha values 2060 float m = alpha / lastAlpha[screen]; 2061 2062 float[] cdata = mvertexData[screen]; 2063 for (int i = 0, j = colorOffset; i < vertexCount; 2064 i++, j+=stride) { 2065 cdata[j+3] *= m; 2066 } 2067 } 2068 } else { 2069 // color data is modified 2070 if (screen == 0) { 2071 // just update alpha values since screen 0 data is 2072 // already updated in setupMirrorColorPointer 2073 2074 float[] cdata = mvertexData[screen]; 2075 double m = alpha / lastAlpha[0]; 2076 2077 for (int i = 0, j = colorOffset; i < vertexCount; 2078 i++, j+=stride) { 2079 cdata[j+3] *= m; 2080 } 2081 } else { 2082 // update color values from screen 0 data 2083 2084 float m = alpha / lastAlpha[0]; 2085 float[] sdata = mvertexData[0]; 2086 float[] cdata = mvertexData[screen]; 2087 2088 for (int i = 0, j = colorOffset; i < vertexCount; 2089 i++, j+=stride) { 2090 System.arraycopy(sdata, j, cdata, j, 3); 2091 cdata[j+3] = sdata[j+3] * m; 2092 } 2093 } 2094 } 2095 2096 lastAlpha[screen] = alpha; 2097 colorChanged &= ~(1 << screen); 2098 dirtyFlag |= COLOR_CHANGED; 2099 retVal[1] = mvertexData[screen]; 2100 return retVal; 2101 } 2102 updateAlphaInInterLeavedData(Canvas3D cv, int screen, float alpha)2103 Object[] updateAlphaInInterLeavedData(Canvas3D cv, int screen, float alpha) { 2104 2105 Object[] retVal = new Object[2]; 2106 retVal[0] = Boolean.FALSE; 2107 2108 // no need to update alpha values if canvas supports global alpha 2109 if (cv.supportGlobalAlpha()) { 2110 cv.setGlobalAlpha(cv.ctx, alpha); 2111 retVal[1] = null; 2112 return retVal; 2113 } 2114 2115 // update alpha only if vertex format includes alpha 2116 if (((vertexFormat | c4fAllocated) & GeometryArray.WITH_ALPHA) == 0) { 2117 retVal[1] = mirrorInterleavedColorPointer[0]; 2118 return retVal; 2119 } 2120 int coffset = initialColorIndex << 2; // Each color is 4 floats 2121 2122 // if alpha is smaller than EPSILON, set it to EPSILON, so that 2123 // even if alpha is equal to 0, we will not completely lose 2124 // the original alpha value 2125 if (alpha <= EPSILON) { 2126 alpha = (float)EPSILON; 2127 } 2128 retVal[0] = Boolean.TRUE; 2129 2130 assert lastAlpha != null; 2131 assert mirrorInterleavedColorPointer != null; 2132 assert mirrorInterleavedColorPointer.length == lastAlpha.length; 2133 2134 // Issue 113 - reallocate lastAlpha array if needed, but no need to 2135 // update the values here 2136 if (lastAlpha.length <= screen) { 2137 float[] la = new float[screen + 1]; 2138 for (int i = 0; i < lastAlpha.length; i++) { 2139 la[i] = lastAlpha[i]; 2140 } 2141 lastAlpha = la; 2142 } 2143 2144 // allocate a copy of the vertex data for the screen if needed. 2145 // this piece of code is only for multi-screens case 2146 if (mirrorInterleavedColorPointer.length <= screen) { 2147 2148 float[][] cfData = new float[screen + 1][]; 2149 2150 for (int i = 0; i < mirrorInterleavedColorPointer.length; i++) { 2151 cfData[i] = mirrorInterleavedColorPointer[i]; 2152 } 2153 2154 // Issue 113 - allocate entries for [oldSize..screen]; 2155 // copy cfData[0] to cfData[oldsize..screen-1] and 2156 // lastAlpha[0] to lastAlpha[oldsize..screen-1]. 2157 for (int i = mirrorInterleavedColorPointer.length; i < screen+1; i++) { 2158 cfData[i] = new float[4 * vertexCount]; 2159 System.arraycopy(cfData[0], 0, cfData[i], 0, 4 * vertexCount); 2160 lastAlpha[i] = lastAlpha[0]; 2161 } 2162 2163 mirrorInterleavedColorPointer = cfData; 2164 2165 // Issue 113 - since we copied the data from screen 0, we don't need 2166 // to do any further special processing. 2167 } 2168 2169 assert lastAlpha[screen] >= 0.0; 2170 2171 if ((colorChanged & (1<<screen)) == 0) { 2172 // color data is not modified 2173 if (Math.abs(lastAlpha[screen] - alpha) <= EPSILON) { 2174 // and if alpha is the same as the last one, 2175 // just return the data 2176 retVal[1] = mirrorInterleavedColorPointer[screen]; 2177 return retVal; 2178 } else { 2179 2180 // if alpha is different, update the alpha values 2181 2182 float m = alpha / lastAlpha[screen]; 2183 2184 float[] cdata = mirrorInterleavedColorPointer[screen]; 2185 2186 coffset = initialColorIndex << 2; 2187 for (int i = coffset; i < coffset + (vertexCount << 2); i+=4) { 2188 cdata[i+3] = cdata[i+3] * m; 2189 } 2190 } 2191 } else { 2192 // color data is modified 2193 if (screen == 0) { 2194 2195 // just update alpha values since screen 0 data is 2196 // already updated in setupMirrorInterleavedColorPointer 2197 2198 float[] cdata = mirrorInterleavedColorPointer[screen]; 2199 2200 for (int i = coffset; i < coffset + (vertexCount << 2); i+=4) { 2201 cdata[i+3] = cdata[i+3] * alpha; 2202 } 2203 } else { 2204 // update color values from screen 0 data 2205 2206 float m; 2207 2208 if ((colorChanged & 1) == 0) { 2209 // alpha is up to date in screen 0 2210 m = alpha / lastAlpha[0]; 2211 } else { 2212 m = alpha; 2213 } 2214 2215 float[] sdata = mirrorInterleavedColorPointer[0]; 2216 float[] cdata = mirrorInterleavedColorPointer[screen]; 2217 2218 for (int i = coffset; i < coffset + (vertexCount << 2);) { 2219 // System.arraycopy(sdata, i, cdata, i, 3); 2220 cdata[i] = sdata[i++]; 2221 cdata[i] = sdata[i++]; 2222 cdata[i] = sdata[i++]; 2223 cdata[i] = sdata[i++] * m; 2224 } 2225 } 2226 } 2227 2228 lastAlpha[screen] = alpha; 2229 colorChanged &= ~(1 << screen); 2230 dirtyFlag |= COLOR_CHANGED; 2231 retVal[1] = mirrorInterleavedColorPointer[screen]; 2232 return retVal; 2233 } 2234 2235 2236 // pass < 0 implies underlying library supports multiTexture, so 2237 // use the multiTexture extension to send all texture units 2238 // data in one pass 2239 // pass >= 0 implies one pass for one texture unit state 2240 execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale, boolean updateAlpha, float alpha, int screen, boolean ignoreVertexColors)2241 void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale, 2242 boolean updateAlpha, float alpha, 2243 int screen, 2244 boolean ignoreVertexColors) { 2245 2246 int cdirty; 2247 boolean useAlpha = false; 2248 Object[] retVal; 2249 2250 // Check for by-copy case 2251 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 2252 float[] vdata; 2253 2254 synchronized (this) { 2255 cdirty = dirtyFlag; 2256 if (updateAlpha && !ignoreVertexColors) { 2257 // update the alpha values 2258 retVal = updateAlphaInVertexData(cv, screen, alpha); 2259 useAlpha = (retVal[0] == Boolean.TRUE); 2260 vdata = (float[])retVal[1]; 2261 2262 // D3D only 2263 if (alpha != lastScreenAlpha) { 2264 // handle multiple screen case 2265 lastScreenAlpha = alpha; 2266 cdirty |= COLOR_CHANGED; 2267 } 2268 } else { 2269 vdata = vertexData; 2270 // if transparency switch between on/off 2271 if (lastScreenAlpha != -1) { 2272 lastScreenAlpha = -1; 2273 cdirty |= COLOR_CHANGED; 2274 } 2275 } 2276 // geomLock is get in MasterControl when 2277 // RenderBin render the geometry. So it is safe 2278 // just to set the dirty flag here 2279 dirtyFlag = 0; 2280 } 2281 2282 Pipeline.getPipeline().execute(cv.ctx, 2283 this, geoType, isNonUniformScale, 2284 useAlpha, 2285 ignoreVertexColors, 2286 initialVertexIndex, 2287 validVertexCount, 2288 ((vertexFormat & GeometryArray.COLOR) != 0)?(vertexFormat|GeometryArray.COLOR_4):vertexFormat, 2289 texCoordSetCount, texCoordSetMap, 2290 (texCoordSetMap == null) ? 0 : texCoordSetMap.length, 2291 texCoordSetMapOffset, 2292 cv.numActiveTexUnit, 2293 vertexAttrCount, vertexAttrSizes, 2294 vdata, null, 2295 cdirty); 2296 } 2297 2298 //By reference with java array 2299 else if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 2300 // interleaved data 2301 if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { 2302 if(interLeavedVertexData == null) 2303 return; 2304 2305 float[] cdata = null; 2306 2307 synchronized (this) { 2308 cdirty = dirtyFlag; 2309 if (updateAlpha && !ignoreVertexColors) { 2310 // update the alpha values 2311 retVal = updateAlphaInInterLeavedData(cv, screen, alpha); 2312 useAlpha = (retVal[0] == Boolean.TRUE); 2313 cdata = (float[])retVal[1]; 2314 if (alpha != lastScreenAlpha) { 2315 lastScreenAlpha = alpha; 2316 cdirty |= COLOR_CHANGED; 2317 } 2318 } else { 2319 // if transparency switch between on/off 2320 if (lastScreenAlpha != -1) { 2321 lastScreenAlpha = -1; 2322 cdirty |= COLOR_CHANGED; 2323 } 2324 } 2325 dirtyFlag = 0; 2326 } 2327 2328 Pipeline.getPipeline().execute(cv.ctx, 2329 this, geoType, isNonUniformScale, 2330 useAlpha, 2331 ignoreVertexColors, 2332 initialVertexIndex, 2333 validVertexCount, 2334 vertexFormat, 2335 texCoordSetCount, texCoordSetMap, 2336 (texCoordSetMap == null) ? 0 : texCoordSetMap.length, 2337 texCoordSetMapOffset, 2338 cv.numActiveTexUnit, 2339 vertexAttrCount, vertexAttrSizes, 2340 interLeavedVertexData, cdata, 2341 cdirty); 2342 2343 } // end of interleaved case 2344 2345 // non interleaved data 2346 else { 2347 2348 // Check if a vertexformat is set, but the array is null 2349 // if yes, don't draw anything 2350 if ((vertexType == 0) || 2351 ((vertexType & VERTEX_DEFINED) == 0) || 2352 (((vertexFormat & GeometryArray.COLOR) != 0) && 2353 (vertexType & COLOR_DEFINED) == 0) || 2354 (((vertexFormat & GeometryArray.NORMALS) != 0) && 2355 (vertexType & NORMAL_DEFINED) == 0) || 2356 (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) && 2357 (vertexType & VATTR_DEFINED) == 0) || 2358 (((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) && 2359 (vertexType & TEXCOORD_DEFINED) == 0)) { 2360 return; 2361 } else { 2362 byte[] cbdata = null; 2363 float[] cfdata = null; 2364 2365 if ((vertexType & (CF | C3F | C4F )) != 0) { 2366 2367 synchronized (this) { 2368 cdirty = dirtyFlag; 2369 if (updateAlpha && !ignoreVertexColors) { 2370 cfdata = updateAlphaInFloatRefColors(cv, screen, alpha); 2371 if (alpha != lastScreenAlpha) { 2372 lastScreenAlpha = alpha; 2373 cdirty |= COLOR_CHANGED; 2374 } 2375 } else { 2376 cfdata = mirrorFloatRefColors[0]; 2377 // if transparency switch between on/off 2378 if (lastScreenAlpha != -1) { 2379 lastScreenAlpha = -1; 2380 cdirty |= COLOR_CHANGED; 2381 } 2382 2383 } 2384 dirtyFlag = 0; 2385 } 2386 } // end of color in float format 2387 else if ((vertexType & (CUB| C3UB | C4UB)) != 0) { 2388 synchronized (this) { 2389 cdirty = dirtyFlag; 2390 if (updateAlpha && !ignoreVertexColors) { 2391 cbdata = updateAlphaInByteRefColors(cv, screen, alpha); 2392 if (alpha != lastScreenAlpha) { 2393 lastScreenAlpha = alpha; 2394 cdirty |= COLOR_CHANGED; 2395 } 2396 } else { 2397 cbdata = mirrorUnsignedByteRefColors[0]; 2398 // if transparency switch between on/off 2399 if (lastScreenAlpha != -1) { 2400 lastScreenAlpha = -1; 2401 cdirty |= COLOR_CHANGED; 2402 } 2403 } 2404 dirtyFlag = 0; 2405 } 2406 } // end of color in byte format 2407 else { 2408 cdirty = dirtyFlag; 2409 } 2410 // setup vdefined to passed to native code 2411 int vdefined = 0; 2412 if((vertexType & (PF | P3F)) != 0) 2413 vdefined |= COORD_FLOAT; 2414 if((vertexType & (PD | P3D)) != 0) 2415 vdefined |= COORD_DOUBLE; 2416 if((vertexType & (CF | C3F | C4F)) != 0) 2417 vdefined |= COLOR_FLOAT; 2418 if((vertexType & (CUB| C3UB | C4UB)) != 0) 2419 vdefined |= COLOR_BYTE; 2420 if((vertexType & NORMAL_DEFINED) != 0) 2421 vdefined |= NORMAL_FLOAT; 2422 if((vertexType & VATTR_DEFINED) != 0) 2423 vdefined |= VATTR_FLOAT; 2424 if((vertexType & TEXCOORD_DEFINED) != 0) 2425 vdefined |= TEXCOORD_FLOAT; 2426 2427 Pipeline.getPipeline().executeVA(cv.ctx, 2428 this, geoType, isNonUniformScale, 2429 ignoreVertexColors, 2430 validVertexCount, 2431 (vertexFormat | c4fAllocated), 2432 vdefined, 2433 initialCoordIndex, 2434 mirrorFloatRefCoords, mirrorDoubleRefCoords, 2435 initialColorIndex, cfdata, cbdata, 2436 initialNormalIndex, mirrorFloatRefNormals, 2437 vertexAttrCount, vertexAttrSizes, 2438 initialVertexAttrIndex, mirrorFloatRefVertexAttrs, 2439 ((texCoordSetMap == null) ? 0:texCoordSetMap.length), 2440 texCoordSetMap, 2441 cv.numActiveTexUnit, 2442 initialTexCoordIndex,texCoordStride, 2443 mirrorRefTexCoords, cdirty); 2444 }// end of all vertex data being set 2445 }// end of non interleaved case 2446 }// end of by reference with java array 2447 2448 //By reference with nio buffer 2449 else { 2450 // interleaved data 2451 if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { 2452 2453 if ( interleavedFloatBufferImpl == null) 2454 return; 2455 2456 float[] cdata = null; 2457 synchronized (this) { 2458 cdirty = dirtyFlag; 2459 if (updateAlpha && !ignoreVertexColors) { 2460 // update the alpha values 2461 // XXXX: to handle alpha case 2462 retVal = updateAlphaInInterLeavedData(cv, screen, alpha); 2463 useAlpha = (retVal[0] == Boolean.TRUE); 2464 cdata = (float[])retVal[1]; 2465 2466 if (alpha != lastScreenAlpha) { 2467 lastScreenAlpha = alpha; 2468 cdirty |= COLOR_CHANGED; 2469 } 2470 } else { 2471 // XXXX: to handle alpha case 2472 cdata = null; 2473 // if transparency switch between on/off 2474 if (lastScreenAlpha != -1) { 2475 lastScreenAlpha = -1; 2476 cdirty |= COLOR_CHANGED; 2477 } 2478 } 2479 dirtyFlag = 0; 2480 } 2481 2482 Pipeline.getPipeline().executeInterleavedBuffer(cv.ctx, 2483 this, geoType, isNonUniformScale, 2484 useAlpha, 2485 ignoreVertexColors, 2486 initialVertexIndex, 2487 validVertexCount, 2488 vertexFormat, 2489 texCoordSetCount, texCoordSetMap, 2490 (texCoordSetMap == null) ? 0 : texCoordSetMap.length, 2491 texCoordSetMapOffset, 2492 cv.numActiveTexUnit, 2493 interleavedFloatBufferImpl.getBufferAsObject(), cdata, 2494 cdirty); 2495 2496 } // end of interleaved case 2497 2498 // non interleaved data 2499 else { 2500 2501 // Check if a vertexformat is set, but the array is null 2502 // if yes, don't draw anything 2503 if ((vertexType == 0) || 2504 ((vertexType & VERTEX_DEFINED) == 0) || 2505 (((vertexFormat & GeometryArray.COLOR) != 0) && 2506 (vertexType & COLOR_DEFINED) == 0) || 2507 (((vertexFormat & GeometryArray.NORMALS) != 0) && 2508 (vertexType & NORMAL_DEFINED) == 0) || 2509 (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) && 2510 (vertexType & VATTR_DEFINED) == 0) || 2511 (((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) && 2512 (vertexType & TEXCOORD_DEFINED) == 0)) { 2513 return; 2514 } else { 2515 byte[] cbdata = null; 2516 float[] cfdata = null; 2517 2518 if ((vertexType & CF ) != 0) { 2519 synchronized (this) { 2520 cdirty = dirtyFlag; 2521 if (updateAlpha && !ignoreVertexColors) { 2522 cfdata = updateAlphaInFloatRefColors(cv, 2523 screen, alpha); 2524 if (alpha != lastScreenAlpha) { 2525 lastScreenAlpha = alpha; 2526 cdirty |= COLOR_CHANGED; 2527 } 2528 } else { 2529 // XXXX: handle transparency case 2530 //cfdata = null; 2531 cfdata = mirrorFloatRefColors[0]; 2532 // if transparency switch between on/off 2533 if (lastScreenAlpha != -1) { 2534 lastScreenAlpha = -1; 2535 cdirty |= COLOR_CHANGED; 2536 } 2537 2538 } 2539 dirtyFlag = 0; 2540 } 2541 } // end of color in float format 2542 else if ((vertexType & CUB) != 0) { 2543 synchronized (this) { 2544 cdirty = dirtyFlag; 2545 if (updateAlpha && !ignoreVertexColors) { 2546 cbdata = updateAlphaInByteRefColors( 2547 cv, screen, alpha); 2548 if (alpha != lastScreenAlpha) { 2549 lastScreenAlpha = alpha; 2550 cdirty |= COLOR_CHANGED; 2551 } 2552 } else { 2553 // XXXX: handle transparency case 2554 //cbdata = null; 2555 cbdata = mirrorUnsignedByteRefColors[0]; 2556 // if transparency switch between on/off 2557 if (lastScreenAlpha != -1) { 2558 lastScreenAlpha = -1; 2559 cdirty |= COLOR_CHANGED; 2560 } 2561 } 2562 dirtyFlag = 0; 2563 } 2564 } // end of color in byte format 2565 else { 2566 cdirty = dirtyFlag; 2567 } 2568 2569 Object vcoord = null, cdataBuffer=null, normal=null; 2570 2571 int vdefined = 0; 2572 if((vertexType & PF) != 0) { 2573 vdefined |= COORD_FLOAT; 2574 vcoord = floatBufferRefCoords.getBufferAsObject(); 2575 } else if((vertexType & PD ) != 0) { 2576 vdefined |= COORD_DOUBLE; 2577 vcoord = doubleBufferRefCoords.getBufferAsObject(); 2578 } 2579 2580 if((vertexType & CF ) != 0) { 2581 vdefined |= COLOR_FLOAT; 2582 cdataBuffer = floatBufferRefColors.getBufferAsObject(); 2583 } else if((vertexType & CUB) != 0) { 2584 vdefined |= COLOR_BYTE; 2585 cdataBuffer = byteBufferRefColors.getBufferAsObject(); 2586 } 2587 2588 if((vertexType & NORMAL_DEFINED) != 0) { 2589 vdefined |= NORMAL_FLOAT; 2590 normal = floatBufferRefNormals.getBufferAsObject(); 2591 } 2592 2593 if ((vertexType & VATTR_DEFINED) != 0) { 2594 vdefined |= VATTR_FLOAT; 2595 } 2596 2597 if((vertexType & TEXCOORD_DEFINED) != 0) 2598 vdefined |= TEXCOORD_FLOAT; 2599 2600 Pipeline.getPipeline().executeVABuffer(cv.ctx, 2601 this, geoType, isNonUniformScale, 2602 ignoreVertexColors, 2603 validVertexCount, 2604 (vertexFormat | c4fAllocated), 2605 vdefined, 2606 initialCoordIndex, 2607 vcoord, 2608 initialColorIndex, 2609 cdataBuffer, 2610 cfdata, cbdata, 2611 initialNormalIndex, 2612 normal, 2613 vertexAttrCount, vertexAttrSizes, 2614 initialVertexAttrIndex, 2615 nioFloatBufferRefVertexAttrs, 2616 ((texCoordSetMap == null) ? 0:texCoordSetMap.length), 2617 texCoordSetMap, 2618 cv.numActiveTexUnit, 2619 initialTexCoordIndex,texCoordStride, 2620 refTexCoords, cdirty); 2621 }// end of all vertex data being set 2622 }// end of non interleaved case 2623 }// end of by reference with nio-buffer case 2624 } 2625 buildGA(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale, boolean updateAlpha, float alpha, boolean ignoreVertexColors, Transform3D xform, Transform3D nxform)2626 void buildGA(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale, 2627 boolean updateAlpha, float alpha, boolean ignoreVertexColors, 2628 Transform3D xform, Transform3D nxform) { 2629 2630 float[] vdata = null; 2631 2632 // NIO buffers are no longer supported in display lists 2633 assert (vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0; 2634 2635 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 2636 vdata = vertexData; 2637 } 2638 else if ((vertexFormat & GeometryArray.INTERLEAVED) != 0 && 2639 ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0)) { 2640 vdata = interLeavedVertexData; 2641 } 2642 if (vdata != null) { 2643 /* 2644 System.err.println("calling native buildGA()"); 2645 System.err.println("geoType = "+geoType+" initialVertexIndex = "+initialVertexIndex+" validVertexCount = "+validVertexCount+" vertexFormat = "+vertexFormat+" vertexData = "+vertexData); 2646 */ 2647 Pipeline.getPipeline().buildGA(cv.ctx, 2648 this, geoType, isNonUniformScale, 2649 updateAlpha, alpha, ignoreVertexColors, 2650 initialVertexIndex, 2651 validVertexCount, vertexFormat, 2652 texCoordSetCount, texCoordSetMap, 2653 (texCoordSetMap == null) ? 0 : texCoordSetMap.length, 2654 texCoordSetMapOffset, 2655 vertexAttrCount, vertexAttrSizes, 2656 (xform == null) ? null : xform.mat, 2657 (nxform == null) ? null : nxform.mat, 2658 vdata); 2659 } 2660 else { 2661 // Check if a vertexformat is set, but the array is null 2662 // if yes, don't draw anything 2663 if ((vertexType == 0) || 2664 ((vertexType & VERTEX_DEFINED) == 0) || 2665 (((vertexFormat & GeometryArray.COLOR) != 0) && 2666 (vertexType & COLOR_DEFINED) == 0) || 2667 (((vertexFormat & GeometryArray.NORMALS) != 0) && 2668 (vertexType & NORMAL_DEFINED) == 0) || 2669 (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) && 2670 (vertexType & VATTR_DEFINED) == 0) || 2671 (((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) && 2672 (vertexType & TEXCOORD_DEFINED) == 0)) { 2673 2674 return; 2675 } 2676 2677 // Either non-interleaved, by-ref or nio buffer 2678 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 2679 // Java array case 2680 // setup vdefined to passed to native code 2681 int vdefined = 0; 2682 if((vertexType & (PF | P3F)) != 0) 2683 vdefined |= COORD_FLOAT; 2684 if((vertexType & (PD | P3D)) != 0) 2685 vdefined |= COORD_DOUBLE; 2686 if((vertexType & (CF | C3F | C4F)) != 0) 2687 vdefined |= COLOR_FLOAT; 2688 if((vertexType & (CUB| C3UB | C4UB)) != 0) 2689 vdefined |= COLOR_BYTE; 2690 if((vertexType & NORMAL_DEFINED) != 0) 2691 vdefined |= NORMAL_FLOAT; 2692 if((vertexType & VATTR_DEFINED) != 0) 2693 vdefined |= VATTR_FLOAT; 2694 if((vertexType & TEXCOORD_DEFINED) != 0) 2695 vdefined |= TEXCOORD_FLOAT; 2696 2697 Pipeline.getPipeline().buildGAForByRef(cv.ctx, 2698 this, geoType, isNonUniformScale, 2699 updateAlpha, alpha, 2700 ignoreVertexColors, 2701 validVertexCount, 2702 vertexFormat, 2703 vdefined, 2704 initialCoordIndex, 2705 mirrorFloatRefCoords, mirrorDoubleRefCoords, 2706 initialColorIndex, mirrorFloatRefColors[0], mirrorUnsignedByteRefColors[0], 2707 initialNormalIndex, mirrorFloatRefNormals, 2708 vertexAttrCount, vertexAttrSizes, 2709 initialVertexAttrIndex, mirrorFloatRefVertexAttrs, 2710 ((texCoordSetMap == null) ? 0:texCoordSetMap.length), 2711 texCoordSetMap, 2712 initialTexCoordIndex,texCoordStride, 2713 mirrorRefTexCoords, 2714 (xform == null) ? null : xform.mat, 2715 (nxform == null) ? null : nxform.mat); 2716 } 2717 /* 2718 // NOTE: NIO buffers are no longer supported in display lists. 2719 // This was never enabled by default anyway (only when the 2720 // optimizeForSpace property was set to false), so it wasn't 2721 // well-tested. If future support is desired, we will need to 2722 // add vertex attributes to buildGAForBuffer. There are no plans 2723 // to ever do this. 2724 else { 2725 // NIO Buffer case 2726 Object vcoord = null, cdataBuffer=null, normal=null; 2727 2728 int vdefined = 0; 2729 if((vertexType & PF) != 0) { 2730 vdefined |= COORD_FLOAT; 2731 vcoord = floatBufferRefCoords.getBufferAsObject(); 2732 } else if((vertexType & PD ) != 0) { 2733 vdefined |= COORD_DOUBLE; 2734 vcoord = doubleBufferRefCoords.getBufferAsObject(); 2735 } 2736 2737 if((vertexType & CF ) != 0) { 2738 vdefined |= COLOR_FLOAT; 2739 cdataBuffer = floatBufferRefColors.getBufferAsObject(); 2740 } else if((vertexType & CUB) != 0) { 2741 vdefined |= COLOR_BYTE; 2742 cdataBuffer = byteBufferRefColors.getBufferAsObject(); 2743 } 2744 2745 if((vertexType & NORMAL_DEFINED) != 0) { 2746 vdefined |= NORMAL_FLOAT; 2747 normal = floatBufferRefNormals.getBufferAsObject(); 2748 } 2749 2750 if((vertexType & TEXCOORD_DEFINED) != 0) 2751 vdefined |= TEXCOORD_FLOAT; 2752 // NOTE : need to add vertex attrs 2753 Pipeline.getPipeline().buildGAForBuffer(cv.ctx, 2754 this, geoType, isNonUniformScale, 2755 updateAlpha, alpha, 2756 ignoreVertexColors, 2757 validVertexCount, 2758 vertexFormat, 2759 vdefined, 2760 initialCoordIndex, 2761 vcoord, 2762 initialColorIndex,cdataBuffer, 2763 initialNormalIndex, normal, 2764 ((texCoordSetMap == null) ? 0:texCoordSetMap.length), 2765 texCoordSetMap, 2766 initialTexCoordIndex,texCoordStride, 2767 refTexCoords, 2768 (xform == null) ? null : xform.mat, 2769 (nxform == null) ? null : nxform.mat); 2770 } 2771 */ 2772 2773 } 2774 2775 } 2776 unIndexify(IndexedGeometryArrayRetained src)2777 void unIndexify(IndexedGeometryArrayRetained src) { 2778 if ((src.vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 2779 unIndexifyJavaArray(src); 2780 } 2781 else { 2782 unIndexifyNIOBuffer(src); 2783 } 2784 } 2785 unIndexifyJavaArray(IndexedGeometryArrayRetained src)2786 private void unIndexifyJavaArray(IndexedGeometryArrayRetained src) { 2787 // System.err.println("unIndexifyJavaArray"); 2788 2789 int vOffset = 0, srcOffset, tOffset = 0; 2790 int index, colorStride = 0; 2791 float[] vdata = null; 2792 int i; 2793 int start, end; 2794 start = src.initialIndexIndex; 2795 end = src.initialIndexIndex + src.validIndexCount; 2796 // If its either "normal" data or interleaved data then .. 2797 if (((src.vertexFormat & GeometryArray.BY_REFERENCE) == 0) || 2798 ((src.vertexFormat & GeometryArray.INTERLEAVED) != 0)) { 2799 2800 if ((src.vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 2801 vdata = src.vertexData; 2802 if ((src.vertexFormat & GeometryArray.COLOR) != 0) 2803 colorStride = 4; 2804 } 2805 else if ((src.vertexFormat & GeometryArray.INTERLEAVED) != 0) { 2806 vdata = src.interLeavedVertexData; 2807 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 2808 colorStride = 4; 2809 else if ((src.vertexFormat & GeometryArray.COLOR) != 0) 2810 colorStride = 3; 2811 } 2812 2813 // System.err.println("===> start = "+start+" end = "+end); 2814 for (index= start; index < end; index++) { 2815 if ((vertexFormat & GeometryArray.NORMALS) != 0){ 2816 System.arraycopy(vdata, 2817 src.indexNormal[index]*src.stride + src.normalOffset, 2818 vertexData, vOffset + normalOffset, 3); 2819 } 2820 if (colorStride == 4){ 2821 // System.err.println("===> copying color3"); 2822 System.arraycopy(vdata, 2823 src.indexColor[index]*src.stride + src.colorOffset, 2824 vertexData, vOffset + colorOffset, colorStride); 2825 } else if (colorStride == 3) { 2826 // System.err.println("===> copying color4"); 2827 System.arraycopy(vdata, 2828 src.indexColor[index]*src.stride + src.colorOffset, 2829 vertexData, vOffset + colorOffset, colorStride); 2830 vertexData[vOffset + colorOffset + 3] = 1.0f; 2831 } 2832 2833 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 2834 int tcOffset = vOffset + textureOffset; 2835 int interleavedOffset = 0; 2836 2837 for (i = 0; i < texCoordSetCount; 2838 i++, tcOffset += texCoordStride) { 2839 2840 if ((src.vertexFormat & GeometryArray.INTERLEAVED) != 0) { 2841 interleavedOffset = i * texCoordStride; 2842 } 2843 2844 System.arraycopy(vdata, 2845 (src.indexTexCoord[i][index])*src.stride + src.textureOffset + interleavedOffset, 2846 vertexData, tcOffset, texCoordStride); 2847 } 2848 } 2849 2850 if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 2851 // vertex attributes can't be interleaved 2852 assert (src.vertexFormat & GeometryArray.INTERLEAVED) == 0; 2853 2854 for (i = 0; i < vertexAttrCount; i++) { 2855 int vaOffset = vOffset + vertexAttrOffsets[i]; 2856 2857 System.arraycopy(vdata, 2858 (src.indexVertexAttr[i][index])*src.stride + src.vertexAttrOffsets[i], 2859 vertexData, vaOffset, vertexAttrSizes[i]); 2860 } 2861 } 2862 2863 if ((vertexFormat & GeometryArray.COORDINATES) != 0){ 2864 // System.err.println("===> copying coords"); 2865 System.arraycopy(vdata, 2866 src.indexCoord[index]*src.stride 2867 + src.coordinateOffset, 2868 vertexData, 2869 vOffset + coordinateOffset, 3); 2870 } 2871 vOffset += stride; 2872 } 2873 2874 } else { 2875 if ((vertexFormat & GeometryArray.NORMALS) != 0) { 2876 vOffset = normalOffset; 2877 switch ((src.vertexType & NORMAL_DEFINED)) { 2878 case NF: 2879 for (index=start; index < end; index++) { 2880 System.arraycopy(src.floatRefNormals, 2881 src.indexNormal[index]*3, 2882 vertexData, 2883 vOffset, 3); 2884 vOffset += stride; 2885 } 2886 break; 2887 case N3F: 2888 for (index=start; index < end; index++) { 2889 srcOffset = src.indexNormal[index]; 2890 vertexData[vOffset] = src.v3fRefNormals[srcOffset].x; 2891 vertexData[vOffset+1] = src.v3fRefNormals[srcOffset].y; 2892 vertexData[vOffset+2] = src.v3fRefNormals[srcOffset].z; 2893 vOffset += stride; 2894 } 2895 break; 2896 default: 2897 break; 2898 } 2899 } 2900 2901 if ((vertexFormat & GeometryArray.COLOR) != 0) { 2902 vOffset = colorOffset; 2903 int multiplier = 3; 2904 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 2905 multiplier = 4; 2906 2907 switch ((src.vertexType & COLOR_DEFINED)) { 2908 case CF: 2909 for (index=start; index < end; index++) { 2910 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) { 2911 System.arraycopy(src.floatRefColors, 2912 src.indexColor[index]*multiplier, 2913 vertexData, 2914 vOffset, 4); 2915 } 2916 else { 2917 System.arraycopy(src.floatRefColors, 2918 src.indexColor[index]*multiplier, 2919 vertexData, 2920 vOffset, 3); 2921 vertexData[vOffset+3] = 1.0f; 2922 } 2923 vOffset += stride; 2924 } 2925 break; 2926 case CUB: 2927 for (index=start; index < end; index++) { 2928 srcOffset = src.indexColor[index] * multiplier; 2929 vertexData[vOffset] = (src.byteRefColors[srcOffset] & 0xff) * ByteToFloatScale; 2930 vertexData[vOffset+1] = (src.byteRefColors[srcOffset+1] & 0xff) * ByteToFloatScale; 2931 vertexData[vOffset+2] = (src.byteRefColors[srcOffset+2] & 0xff) * ByteToFloatScale; 2932 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) { 2933 vertexData[vOffset+3] = (src.byteRefColors[srcOffset+3] & 0xff) * ByteToFloatScale; 2934 } 2935 else { 2936 vertexData[vOffset+3] = 1.0f; 2937 } 2938 vOffset += stride; 2939 } 2940 break; 2941 case C3F: 2942 for (index=start; index < end; index++) { 2943 srcOffset = src.indexColor[index]; 2944 vertexData[vOffset] = src.c3fRefColors[srcOffset].x; 2945 vertexData[vOffset+1] = src.c3fRefColors[srcOffset].y; 2946 vertexData[vOffset+2] = src.c3fRefColors[srcOffset].z; 2947 vertexData[vOffset+3] = 1.0f; 2948 vOffset += stride; 2949 } 2950 break; 2951 case C4F: 2952 for (index=start; index < end; index++) { 2953 srcOffset = src.indexColor[index]; 2954 vertexData[vOffset] = src.c4fRefColors[srcOffset].x; 2955 vertexData[vOffset+1] = src.c4fRefColors[srcOffset].y; 2956 vertexData[vOffset+2] = src.c4fRefColors[srcOffset].z; 2957 vertexData[vOffset+3] = src.c4fRefColors[srcOffset].w; 2958 vOffset += stride; 2959 } 2960 break; 2961 case C3UB: 2962 for (index=start; index < end; index++) { 2963 srcOffset = src.indexColor[index]; 2964 vertexData[vOffset] = (src.c3bRefColors[srcOffset].x & 0xff) * ByteToFloatScale; 2965 vertexData[vOffset+1] = (src.c3bRefColors[srcOffset].y & 0xff) * ByteToFloatScale; 2966 vertexData[vOffset+2] = (src.c3bRefColors[srcOffset].z & 0xff) * ByteToFloatScale; 2967 vertexData[vOffset+3] = 1.0f; 2968 vOffset += stride; 2969 } 2970 break; 2971 case C4UB: 2972 for (index=start; index < end; index++) { 2973 srcOffset = src.indexColor[index]; 2974 vertexData[vOffset] = (src.c4bRefColors[srcOffset].x & 0xff) * ByteToFloatScale; 2975 vertexData[vOffset+1] = (src.c4bRefColors[srcOffset].y & 0xff) * ByteToFloatScale; 2976 vertexData[vOffset+2] = (src.c4bRefColors[srcOffset].z & 0xff) * ByteToFloatScale; 2977 vertexData[vOffset+3] = (src.c4bRefColors[srcOffset].w & 0xff) * ByteToFloatScale; 2978 vOffset += stride; 2979 } 2980 break; 2981 default: 2982 break; 2983 } 2984 } 2985 2986 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 2987 vOffset = textureOffset; 2988 switch ((src.vertexType & TEXCOORD_DEFINED)) { 2989 case TF: 2990 for (index=start; index < end; index++) { 2991 for (i = 0, tOffset = vOffset; 2992 i < texCoordSetCount; i++) { 2993 System.arraycopy(src.refTexCoords[i], 2994 src.indexTexCoord[i][index]*texCoordStride, 2995 vertexData, tOffset, texCoordStride); 2996 tOffset += texCoordStride; 2997 } 2998 vOffset += stride; 2999 } 3000 break; 3001 case T2F: 3002 for (index=start; index < end; index++) { 3003 for (i = 0, tOffset = vOffset; 3004 i < texCoordSetCount; i++) { 3005 srcOffset = src.indexTexCoord[i][index]; 3006 vertexData[tOffset] = 3007 ((TexCoord2f[])src.refTexCoords[i])[srcOffset].x; 3008 vertexData[tOffset+1] = 3009 ((TexCoord2f[])src.refTexCoords[i])[srcOffset].y; 3010 tOffset += texCoordStride; 3011 } 3012 vOffset += stride; 3013 } 3014 break; 3015 case T3F: 3016 for (index=start; index < end; index++) { 3017 for (i = 0, tOffset = vOffset; 3018 i < texCoordSetCount; i++) { 3019 srcOffset = src.indexTexCoord[i][index]; 3020 vertexData[tOffset] = 3021 ((TexCoord3f[])src.refTexCoords[i])[srcOffset].x; 3022 vertexData[tOffset+1] = 3023 ((TexCoord3f[])src.refTexCoords[i])[srcOffset].y; 3024 vertexData[tOffset+2] = 3025 ((TexCoord3f[])src.refTexCoords[i])[srcOffset].z; 3026 tOffset += texCoordStride; 3027 } 3028 vOffset += stride; 3029 } 3030 break; 3031 default: 3032 break; 3033 } 3034 } 3035 3036 if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 3037 vOffset = 0; 3038 switch (src.vertexType & VATTR_DEFINED) { 3039 case AF: 3040 for (index=start; index < end; index++) { 3041 for (i = 0; i < vertexAttrCount; i++) { 3042 int vaOffset = vOffset + vertexAttrOffsets[i]; 3043 System.arraycopy(src.floatRefVertexAttrs[i], 3044 src.indexVertexAttr[i][index]*vertexAttrSizes[i], 3045 vertexData, vaOffset, vertexAttrSizes[i]); 3046 } 3047 vOffset += stride; 3048 } 3049 break; 3050 } 3051 } 3052 3053 if ((vertexFormat & GeometryArray.COORDINATES) != 0) { 3054 vOffset = coordinateOffset; 3055 switch ((src.vertexType & VERTEX_DEFINED)) { 3056 case PF: 3057 for (index=start; index < end; index++) { 3058 System.arraycopy(src.floatRefCoords, 3059 src.indexCoord[index]*3, 3060 vertexData, 3061 vOffset, 3); 3062 vOffset += stride; 3063 } 3064 break; 3065 case PD: 3066 for (index=start; index < end; index++) { 3067 srcOffset = src.indexCoord[index] * 3; 3068 vertexData[vOffset] = (float)src.doubleRefCoords[srcOffset]; 3069 vertexData[vOffset+1] = (float)src.doubleRefCoords[srcOffset+1]; 3070 vertexData[vOffset+2] = (float)src.doubleRefCoords[srcOffset+2]; 3071 vOffset += stride; 3072 } 3073 break; 3074 case P3F: 3075 for (index=start; index < end; index++) { 3076 srcOffset = src.indexCoord[index]; 3077 vertexData[vOffset] = src.p3fRefCoords[srcOffset].x; 3078 vertexData[vOffset+1] = src.p3fRefCoords[srcOffset].y; 3079 vertexData[vOffset+2] = src.p3fRefCoords[srcOffset].z; 3080 vOffset += stride; 3081 } 3082 break; 3083 case P3D: 3084 for (index=start; index < end; index++) { 3085 srcOffset = src.indexCoord[index]; 3086 vertexData[vOffset] = (float)src.p3dRefCoords[srcOffset].x; 3087 vertexData[vOffset+1] = (float)src.p3dRefCoords[srcOffset].y; 3088 vertexData[vOffset+2] = (float)src.p3dRefCoords[srcOffset].z; 3089 vOffset += stride; 3090 } 3091 break; 3092 default: 3093 break; 3094 } 3095 } 3096 3097 } 3098 } 3099 3100 unIndexifyNIOBuffer(IndexedGeometryArrayRetained src)3101 private void unIndexifyNIOBuffer(IndexedGeometryArrayRetained src) { 3102 // System.err.println("unIndexifyNIOBuffer"); 3103 3104 int vOffset = 0, srcOffset, tOffset = 0; 3105 int index, colorStride = 0; 3106 float[] vdata = null; 3107 int i; 3108 int start, end; 3109 start = src.initialIndexIndex; 3110 end = src.initialIndexIndex + src.validIndexCount; 3111 // If its interleaved data then .. 3112 if ((src.vertexFormat & GeometryArray.INTERLEAVED) != 0) { 3113 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 3114 colorStride = 4; 3115 else if ((src.vertexFormat & GeometryArray.COLOR) != 0) 3116 colorStride = 3; 3117 3118 // System.err.println("===> start = "+start+" end = "+end); 3119 for (index= start; index < end; index++) { 3120 if ((vertexFormat & GeometryArray.NORMALS) != 0){ 3121 src.interleavedFloatBufferImpl.position(src.indexNormal[index]*src.stride + src.normalOffset); 3122 src.interleavedFloatBufferImpl.get(vertexData, vOffset + normalOffset, 3); 3123 } 3124 3125 if (colorStride == 4){ 3126 src.interleavedFloatBufferImpl.position(src.indexColor[index]*src.stride + src.colorOffset); 3127 src.interleavedFloatBufferImpl.get(vertexData, vOffset + colorOffset, colorStride); 3128 } else if (colorStride == 3) { 3129 src.interleavedFloatBufferImpl.position(src.indexColor[index]*src.stride + src.colorOffset); 3130 src.interleavedFloatBufferImpl.get(vertexData, vOffset + colorOffset, colorStride); 3131 vertexData[vOffset + colorOffset + 3] = 1.0f; 3132 } 3133 3134 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 3135 int tcOffset = vOffset + textureOffset; 3136 for (i = 0; i < texCoordSetCount; 3137 i++, tcOffset += texCoordStride) { 3138 3139 src.interleavedFloatBufferImpl.position((src.indexTexCoord[i][index])*src.stride + 3140 src.textureOffset); 3141 src.interleavedFloatBufferImpl.get(vertexData, tcOffset, texCoordStride); 3142 } 3143 } 3144 if ((vertexFormat & GeometryArray.COORDINATES) != 0){ 3145 src.interleavedFloatBufferImpl.position(src.indexCoord[index]*src.stride + src.coordinateOffset ); 3146 src.interleavedFloatBufferImpl.get(vertexData, vOffset + coordinateOffset, 3); 3147 } 3148 vOffset += stride; 3149 } 3150 3151 } else { 3152 if ((vertexFormat & GeometryArray.NORMALS) != 0){ 3153 vOffset = normalOffset; 3154 if ((src.vertexType & NORMAL_DEFINED) != 0) { 3155 for (index=start; index < end; index++) { 3156 src.floatBufferRefNormals.position(src.indexNormal[index]*3); 3157 src.floatBufferRefNormals.get(vertexData, vOffset, 3); 3158 vOffset += stride; 3159 } 3160 } 3161 } 3162 3163 if ((vertexFormat & GeometryArray.COLOR) != 0){ 3164 vOffset = colorOffset; 3165 int multiplier = 3; 3166 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 3167 multiplier = 4; 3168 3169 switch ((src.vertexType & COLOR_DEFINED)) { 3170 case CF: 3171 for (index=start; index < end; index++) { 3172 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) { 3173 src.floatBufferRefColors.position(src.indexColor[index]*multiplier); 3174 src.floatBufferRefColors.get(vertexData, vOffset, 4); 3175 } 3176 else { 3177 src.floatBufferRefColors.position(src.indexColor[index]*multiplier); 3178 src.floatBufferRefColors.get(vertexData, vOffset, 3); 3179 vertexData[vOffset+3] = 1.0f; 3180 } 3181 vOffset += stride; 3182 } 3183 break; 3184 case CUB: 3185 for (index=start; index < end; index++) { 3186 srcOffset = src.indexColor[index] * multiplier; 3187 vertexData[vOffset] = (src.byteBufferRefColors.get(srcOffset) & 0xff) * ByteToFloatScale; 3188 vertexData[vOffset+1] = (src.byteBufferRefColors.get(srcOffset+1) & 0xff) * ByteToFloatScale; 3189 vertexData[vOffset+2] = (src.byteBufferRefColors.get(srcOffset+2) & 0xff) * ByteToFloatScale; 3190 3191 if ((src.vertexFormat & GeometryArray.WITH_ALPHA) != 0) { 3192 vertexData[vOffset+3] = (src.byteBufferRefColors.get(srcOffset+3) & 0xff) * ByteToFloatScale; 3193 } 3194 else { 3195 vertexData[vOffset+3] = 1.0f; 3196 } 3197 vOffset += stride; 3198 } 3199 break; 3200 default: 3201 break; 3202 } 3203 } 3204 3205 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 3206 vOffset = textureOffset; 3207 FloatBufferWrapper texBuffer; 3208 if ((src.vertexType & TEXCOORD_DEFINED) != 0) { 3209 for (index=start; index < end; index++) { 3210 for (i = 0, tOffset = vOffset; 3211 i < texCoordSetCount; i++) { 3212 texBuffer = (FloatBufferWrapper)(((J3DBuffer) (src.refTexCoordsBuffer[i])).getBufferImpl()); 3213 texBuffer.position(src.indexTexCoord[i][index]*texCoordStride); 3214 texBuffer.get(vertexData, tOffset, texCoordStride); 3215 tOffset += texCoordStride; 3216 } 3217 vOffset += stride; 3218 } 3219 } 3220 } 3221 3222 if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 3223 vOffset = 0; 3224 if ((src.vertexType & VATTR_DEFINED) == AF) { 3225 for (index=start; index < end; index++) { 3226 for (i = 0; i < vertexAttrCount; i++) { 3227 int vaOffset = vOffset + vertexAttrOffsets[i]; 3228 FloatBufferWrapper vaBuffer = src.floatBufferRefVertexAttrs[i]; 3229 vaBuffer.position(src.indexVertexAttr[i][index]*vertexAttrSizes[i]); 3230 vaBuffer.get(vertexData, vaOffset, vertexAttrSizes[i]); 3231 } 3232 vOffset += stride; 3233 } 3234 } 3235 } 3236 3237 if ((vertexFormat & GeometryArray.COORDINATES) != 0){ 3238 vOffset = coordinateOffset; 3239 switch ((src.vertexType & VERTEX_DEFINED)) { 3240 case PF: 3241 for (index=start; index < end; index++) { 3242 src.floatBufferRefCoords.position(src.indexCoord[index]*3); 3243 src.floatBufferRefCoords.get(vertexData, vOffset, 3); 3244 vOffset += stride; 3245 } 3246 break; 3247 case PD: 3248 for (index=start; index < end; index++) { 3249 srcOffset = src.indexCoord[index] * 3; 3250 vertexData[vOffset] = (float)src.doubleBufferRefCoords.get(srcOffset); 3251 vertexData[vOffset+1] = (float)src.doubleBufferRefCoords.get(srcOffset+1); 3252 vertexData[vOffset+2] = (float)src.doubleBufferRefCoords.get(srcOffset+2); 3253 vOffset += stride; 3254 } 3255 break; 3256 default: 3257 break; 3258 } 3259 } 3260 3261 } 3262 } 3263 3264 3265 /** 3266 * Returns the vertex stride in numbers of floats as a function 3267 * of the vertexFormat. 3268 * @return the stride in floats for this vertex array 3269 */ stride()3270 int stride() 3271 { 3272 int stride = 0; 3273 3274 if((this.vertexFormat & GeometryArray.COORDINATES) != 0) stride += 3; 3275 if((this.vertexFormat & GeometryArray.NORMALS) != 0) stride += 3; 3276 3277 if ((this.vertexFormat & GeometryArray.COLOR) != 0) { 3278 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 3279 // By copy 3280 stride += 4; 3281 } else { 3282 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) == 0) { 3283 stride += 3; 3284 } 3285 else { 3286 stride += 4; 3287 } 3288 } 3289 } 3290 3291 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 3292 3293 if ((this.vertexFormat & 3294 GeometryArray.TEXTURE_COORDINATE_2) != 0) { 3295 texCoordStride = 2; 3296 } else if ((this.vertexFormat & 3297 GeometryArray.TEXTURE_COORDINATE_3) != 0) { 3298 texCoordStride = 3; 3299 } else if ((this.vertexFormat & 3300 GeometryArray.TEXTURE_COORDINATE_4) != 0) { 3301 texCoordStride = 4; 3302 } 3303 3304 stride += texCoordStride * texCoordSetCount; 3305 } 3306 3307 if ((this.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 3308 stride += vertexAttrStride; 3309 } 3310 3311 //System.err.println("stride() = " + stride); 3312 return stride; 3313 } 3314 texCoordSetMapOffset()3315 int[] texCoordSetMapOffset() 3316 { 3317 if (texCoordSetMap == null) 3318 return null; 3319 3320 texCoordSetMapOffset = new int[texCoordSetMap.length]; 3321 for (int i = 0; i < texCoordSetMap.length; i++) { 3322 if (texCoordSetMap[i] == -1) { 3323 texCoordSetMapOffset[i] = -1; 3324 } else { 3325 texCoordSetMapOffset[i] = texCoordSetMap[i] * texCoordStride; 3326 } 3327 } 3328 return texCoordSetMapOffset; 3329 } 3330 3331 /** 3332 * Returns the stride of the set of vertex attributes. This is the 3333 * sum of the sizes of each vertex attribute. 3334 * @return the stride of the vertex attribute data 3335 */ vertexAttrStride()3336 int vertexAttrStride() { 3337 int sum = 0; 3338 for (int i = 0; i < vertexAttrCount; i++) { 3339 sum += vertexAttrSizes[i]; 3340 } 3341 return sum; 3342 } 3343 3344 /** 3345 * Returns the offset in number of floats from the start of a vertex to 3346 * each per-vertex vertex attribute. 3347 * @return array of offsets in floats vertex start to the vertex attribute data 3348 */ vertexAttrOffsets()3349 int[] vertexAttrOffsets() { 3350 int[] offsets; 3351 3352 // Create array of offsets to the start of each vertex attribute. 3353 // The offset of the first attribute is always 0. If no vertex attributes exist, 3354 // then we will allocate an array of length 1 to avoid some checking elsewhere. 3355 if (vertexAttrCount > 0) { 3356 offsets = new int[vertexAttrCount]; 3357 } 3358 else { 3359 offsets = new int[1]; 3360 } 3361 offsets[0] = 0; 3362 for (int i = 1; i < vertexAttrCount; i++) { 3363 offsets[i] = offsets[i-1] + vertexAttrSizes[i-1]; 3364 } 3365 3366 return offsets; 3367 } 3368 3369 /** 3370 * Returns the offset in number of floats from the start of a vertex to 3371 * the per-vertex texture coordinate data. 3372 * texture coordinate data always follows vertex attribute data 3373 * @return the offset in floats vertex start to the tetxure data 3374 */ textureOffset()3375 int textureOffset() 3376 { 3377 int offset = vertexAttrOffsets[0]; 3378 3379 if ((this.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 3380 offset += vertexAttrStride; 3381 } 3382 3383 return offset; 3384 } 3385 3386 /** 3387 * Returns the offset in number of floats from the start of a vertex to 3388 * the per-vertex color data. 3389 * color data always follows texture data 3390 * @param vertexFormat the vertex format for this array 3391 * @return the offset in floats vertex start to the color data 3392 */ colorOffset()3393 int colorOffset() 3394 { 3395 int offset = textureOffset; 3396 3397 if((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) 3398 offset += 2 * texCoordSetCount; 3399 else if((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) 3400 offset += 3 * texCoordSetCount; 3401 else if((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) 3402 offset += 4 * texCoordSetCount; 3403 3404 return offset; 3405 } 3406 3407 /** 3408 * Returns the offset in number of floats from the start of a vertex to 3409 * the per-vertex normal data. 3410 * normal data always follows color data 3411 * @return the offset in floats from the start of a vertex to the normal 3412 */ normalOffset()3413 int normalOffset() 3414 { 3415 int offset = colorOffset; 3416 3417 if ((this.vertexFormat & GeometryArray.COLOR) != 0) { 3418 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 3419 offset += 4; 3420 } else { 3421 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) == 0) { 3422 offset += 3; 3423 } 3424 else { 3425 offset += 4; 3426 } 3427 } 3428 } 3429 return offset; 3430 } 3431 3432 /** 3433 * Returns the offset in number of floats from the start of a vertex to 3434 * the per vertex coordinate data. 3435 * @return the offset in floats vertex start to the coordinate data 3436 */ coordinateOffset()3437 int coordinateOffset() 3438 { 3439 int offset = normalOffset; 3440 3441 if ((this.vertexFormat & GeometryArray.NORMALS) != 0) offset += 3; 3442 return offset; 3443 } 3444 3445 /** 3446 * Returns number of vertices in the GeometryArray 3447 * @return vertexCount number of vertices in the GeometryArray 3448 */ getVertexCount()3449 int getVertexCount(){ 3450 return vertexCount; 3451 } 3452 3453 /** 3454 * Returns vertexFormat in the GeometryArray 3455 * @return vertexFormat format of vertices in the GeometryArray 3456 */ getVertexFormat()3457 int getVertexFormat(){ 3458 return vertexFormat; 3459 } 3460 3461 /** 3462 * Retrieves the number of vertex attributes in this GeometryArray 3463 * object. 3464 * 3465 * @return the number of vertex attributes in this GeometryArray 3466 * object 3467 */ getVertexAttrCount()3468 int getVertexAttrCount() { 3469 return vertexAttrCount; 3470 } 3471 3472 3473 /** 3474 * Retrieves the vertex attribute sizes array from this 3475 * GeometryArray object. 3476 * 3477 * @param vertexAttrSizes an array that will receive a copy of 3478 * the vertex attribute sizes array. The array must hold at least 3479 * <code>vertexAttrCount</code> elements. 3480 */ getVertexAttrSizes(int[] vertexAttrSizes)3481 void getVertexAttrSizes(int[] vertexAttrSizes) { 3482 for (int i = 0; i < vertexAttrCount; i++) { 3483 vertexAttrSizes[i] = this.vertexAttrSizes[i]; 3484 } 3485 } 3486 3487 3488 sendDataChangedMessage(boolean coordinatesChanged)3489 void sendDataChangedMessage(boolean coordinatesChanged) { 3490 J3dMessage[] m; 3491 int i, j, k, index, numShapeMessages, numMorphMessages; 3492 ArrayList shapeList; 3493 Shape3DRetained s; 3494 ArrayList morphList; 3495 MorphRetained morph; 3496 3497 synchronized(liveStateLock) { 3498 if (source != null && source.isLive()) { 3499 // System.err.println("In GeometryArrayRetained - "); 3500 3501 // Send a message to renderBin to rebuild the display list or 3502 // process the vertex array accordingly 3503 // XXXX: Should I send one per universe, isn't display list 3504 // shared by all context/universes? 3505 int threads = J3dThread.UPDATE_RENDER; 3506 // If the geometry type is Indexed then we need to clone the geometry 3507 // We also need to update the cachedChangedFrequent flag 3508 threads |= J3dThread.UPDATE_RENDERING_ATTRIBUTES; 3509 3510 synchronized (universeList) { 3511 numShapeMessages = universeList.size(); 3512 m = new J3dMessage[numShapeMessages]; 3513 3514 k = 0; 3515 3516 for (i = 0; i < numShapeMessages; i++, k++) { 3517 gaList.clear(); 3518 3519 shapeList = (ArrayList)userLists.get(i); 3520 for (j=0; j<shapeList.size(); j++) { 3521 s = (Shape3DRetained)shapeList.get(j); 3522 LeafRetained src = (LeafRetained)s.sourceNode; 3523 // Should only need to update distinct localBounds. 3524 if (coordinatesChanged && src.boundsAutoCompute) { 3525 src.boundsDirty = true; 3526 } 3527 } 3528 3529 for (j=0; j<shapeList.size(); j++) { 3530 s = (Shape3DRetained)shapeList.get(j); 3531 LeafRetained src = (LeafRetained)s.sourceNode; 3532 if (src.boundsDirty) { 3533 // update combine bounds of mirrorShape3Ds. So we need to 3534 // use its bounds and not localBounds. 3535 // bounds is actually a reference to 3536 // mirrorShape3D.source.localBounds. 3537 src.updateBounds(); 3538 src.boundsDirty = false; 3539 } 3540 gaList.add(Shape3DRetained.getGeomAtom(s)); 3541 } 3542 3543 m[k] = new J3dMessage(); 3544 3545 m[k].type = J3dMessage.GEOMETRY_CHANGED; 3546 // Who to send this message to ? 3547 m[k].threads = threads; 3548 m[k].args[0] = gaList.toArray(); 3549 m[k].args[1] = this; 3550 m[k].args[2]= null; 3551 m[k].args[3] = new Integer(changedFrequent); 3552 m[k].universe=(VirtualUniverse)universeList.get(i); 3553 } 3554 VirtualUniverse.mc.processMessage(m); 3555 } 3556 3557 if (morphUniverseList != null) { 3558 synchronized (morphUniverseList) { 3559 numMorphMessages = morphUniverseList.size(); 3560 3561 // take care of morph that is referencing this geometry 3562 if (numMorphMessages > 0) { 3563 synchronized (morphUniverseList) { 3564 for (i = 0; i < numMorphMessages; i++, k++) { 3565 morphList = (ArrayList)morphUserLists.get(i); 3566 for (j=0; j<morphList.size(); j++) { 3567 morph = (MorphRetained)morphList.get(j); 3568 morph.updateMorphedGeometryArray(this, coordinatesChanged); 3569 } 3570 } 3571 } 3572 } 3573 } 3574 } 3575 } 3576 } 3577 3578 } 3579 /** 3580 * Sets the coordinate associated with the vertex at 3581 * the specified index. 3582 * @param index the vertex index 3583 * @param coordinate an array of 3 values containing the new coordinate 3584 */ setCoordinate(int index, float coordinate[])3585 void setCoordinate(int index, float coordinate[]) { 3586 int offset = this.stride * index + coordinateOffset; 3587 boolean isLive = source!=null && source.isLive(); 3588 if(isLive){ 3589 geomLock.getLock(); 3590 } 3591 dirtyFlag |= COORDINATE_CHANGED; 3592 3593 this.vertexData[offset] = coordinate[0]; 3594 this.vertexData[offset+1]= coordinate[1]; 3595 this.vertexData[offset+2]= coordinate[2]; 3596 3597 if (isLive) { 3598 geomLock.unLock(); 3599 } 3600 if (inUpdater || (source == null)) { 3601 return; 3602 } 3603 if (!isLive) { 3604 boundsDirty = true; 3605 return; 3606 } 3607 3608 // Compute geo's bounds 3609 processCoordsChanged(false); 3610 sendDataChangedMessage(true); 3611 3612 } 3613 3614 /** 3615 * Sets the coordinate associated with the vertex at 3616 * the specified index. 3617 * @param index the vertex index 3618 * @param coordinate an array of 3 values containing the new coordinate 3619 */ setCoordinate(int index, double coordinate[])3620 void setCoordinate(int index, double coordinate[]) { 3621 int offset = this.stride * index + coordinateOffset; 3622 boolean isLive = source!=null && source.isLive(); 3623 if(isLive){ 3624 geomLock.getLock(); 3625 } 3626 dirtyFlag |= COORDINATE_CHANGED; 3627 this.vertexData[offset] = (float)coordinate[0]; 3628 this.vertexData[offset+1]= (float)coordinate[1]; 3629 this.vertexData[offset+2]= (float)coordinate[2]; 3630 3631 if(isLive) { 3632 geomLock.unLock(); 3633 } 3634 3635 if (inUpdater || (source == null)) { 3636 return; 3637 } 3638 if (!isLive) { 3639 boundsDirty = true; 3640 return; 3641 } 3642 3643 // Compute geo's bounds 3644 processCoordsChanged(false); 3645 sendDataChangedMessage(true); 3646 } 3647 3648 /** 3649 * Sets the coordinate associated with the vertex at 3650 * the specified index. 3651 * @param index the vertex index 3652 * @param coordinate a vector containing the new coordinate 3653 */ setCoordinate(int index, Point3f coordinate)3654 void setCoordinate(int index, Point3f coordinate) { 3655 int offset = this.stride * index + coordinateOffset; 3656 boolean isLive = source!=null && source.isLive(); 3657 if(isLive){ 3658 geomLock.getLock(); 3659 } 3660 dirtyFlag |= COORDINATE_CHANGED; 3661 this.vertexData[offset] = coordinate.x; 3662 this.vertexData[offset+1]= coordinate.y; 3663 this.vertexData[offset+2]= coordinate.z; 3664 3665 if(isLive) { 3666 geomLock.unLock(); 3667 } 3668 if (inUpdater || (source == null)) { 3669 return; 3670 } 3671 if (!isLive) { 3672 boundsDirty = true; 3673 return; 3674 } 3675 3676 // Compute geo's bounds 3677 processCoordsChanged(false); 3678 sendDataChangedMessage(true); 3679 } 3680 3681 /** 3682 * Sets the coordinate associated with the vertex at 3683 * the specified index. 3684 * @param index the vertex index 3685 * @param coordinate a vector containing the new coordinate 3686 */ setCoordinate(int index, Point3d coordinate)3687 void setCoordinate(int index, Point3d coordinate) { 3688 int offset = this.stride * index + coordinateOffset; 3689 boolean isLive = source!=null && source.isLive(); 3690 if(isLive){ 3691 geomLock.getLock(); 3692 } 3693 dirtyFlag |= COORDINATE_CHANGED; 3694 this.vertexData[offset] = (float)coordinate.x; 3695 this.vertexData[offset+1]= (float)coordinate.y; 3696 this.vertexData[offset+2]= (float)coordinate.z; 3697 if(isLive) { 3698 geomLock.unLock(); 3699 } 3700 if (inUpdater || source == null ) { 3701 return; 3702 } 3703 if (!isLive) { 3704 boundsDirty = true; 3705 return; 3706 } 3707 // Compute geo's bounds 3708 processCoordsChanged(false); 3709 sendDataChangedMessage(true); 3710 } 3711 3712 /** 3713 * Sets the coordinates associated with the vertices starting at 3714 * the specified index. 3715 * @param index the vertex index 3716 * @param coordinates an array of 3*n values containing n new coordinates 3717 */ setCoordinates(int index, float coordinates[])3718 void setCoordinates(int index, float coordinates[]) { 3719 int offset = this.stride * index + coordinateOffset; 3720 int i, j, num = coordinates.length; 3721 boolean isLive = source!=null && source.isLive(); 3722 if(isLive){ 3723 geomLock.getLock(); 3724 } 3725 dirtyFlag |= COORDINATE_CHANGED; 3726 3727 for (i=0, j= offset;i < num; i+=3, j+= this.stride) 3728 { 3729 this.vertexData[j] = coordinates[i]; 3730 this.vertexData[j+1]= coordinates[i+1]; 3731 this.vertexData[j+2]= coordinates[i+2]; 3732 } 3733 3734 if(isLive) { 3735 geomLock.unLock(); 3736 } 3737 if (inUpdater ||source == null ) { 3738 return; 3739 } 3740 if (!isLive) { 3741 boundsDirty = true; 3742 return; 3743 } 3744 3745 // Compute geo's bounds 3746 processCoordsChanged(false); 3747 3748 sendDataChangedMessage(true); 3749 3750 } 3751 3752 /** 3753 * Sets the coordinates associated with the vertices starting at 3754 * the specified index. 3755 * @param index the vertex index 3756 * @param coordinates an array of 3*n values containing n new coordinates 3757 */ setCoordinates(int index, double coordinates[])3758 void setCoordinates(int index, double coordinates[]) { 3759 int offset = this.stride * index + coordinateOffset; 3760 int i, j, num = coordinates.length; 3761 boolean isLive = source!=null && source.isLive(); 3762 if(isLive){ 3763 geomLock.getLock(); 3764 } 3765 dirtyFlag |= COORDINATE_CHANGED; 3766 3767 for (i=0, j= offset;i < num; i+=3, j+= this.stride) 3768 { 3769 this.vertexData[j] = (float)coordinates[i]; 3770 this.vertexData[j+1]= (float)coordinates[i+1]; 3771 this.vertexData[j+2]= (float)coordinates[i+2]; 3772 } 3773 3774 if(isLive) { 3775 geomLock.unLock(); 3776 } 3777 3778 if (inUpdater ||source == null ) { 3779 return; 3780 } 3781 if (!isLive) { 3782 boundsDirty = true; 3783 return; 3784 } 3785 3786 // Compute geo's bounds 3787 processCoordsChanged(false); 3788 3789 sendDataChangedMessage(true); 3790 } 3791 3792 /** 3793 * Sets the coordinates associated with the vertices starting at 3794 * the specified index. 3795 * @param index the vertex index 3796 * @param coordinates an array of vectors containing new coordinates 3797 */ setCoordinates(int index, Point3f coordinates[])3798 void setCoordinates(int index, Point3f coordinates[]) { 3799 int offset = this.stride * index + coordinateOffset; 3800 int i, j, num = coordinates.length; 3801 boolean isLive = source!=null && source.isLive(); 3802 if(isLive){ 3803 geomLock.getLock(); 3804 } 3805 dirtyFlag |= COORDINATE_CHANGED; 3806 3807 for (i=0, j= offset;i < num; i++, j+= this.stride) 3808 { 3809 this.vertexData[j] = coordinates[i].x; 3810 this.vertexData[j+1]= coordinates[i].y; 3811 this.vertexData[j+2]= coordinates[i].z; 3812 } 3813 if(isLive) { 3814 geomLock.unLock(); 3815 } 3816 3817 if (inUpdater ||source == null ) { 3818 return; 3819 } 3820 if (!isLive) { 3821 boundsDirty = true; 3822 return; 3823 } 3824 3825 // Compute geo's bounds 3826 processCoordsChanged(false); 3827 3828 sendDataChangedMessage(true); 3829 3830 } 3831 3832 /** 3833 * Sets the coordinates associated with the vertices starting at 3834 * the specified index. 3835 * @param index the vertex index 3836 * @param coordinates an array of vectors containing new coordinates 3837 */ setCoordinates(int index, Point3d coordinates[])3838 void setCoordinates(int index, Point3d coordinates[]) { 3839 int offset = this.stride * index + coordinateOffset; 3840 int i, j, num = coordinates.length; 3841 boolean isLive = source!=null && source.isLive(); 3842 if(isLive){ 3843 geomLock.getLock(); 3844 } 3845 dirtyFlag |= COORDINATE_CHANGED; 3846 3847 for (i=0, j= offset;i < num; i++, j+= this.stride) 3848 { 3849 this.vertexData[j] = (float)coordinates[i].x; 3850 this.vertexData[j+1]= (float)coordinates[i].y; 3851 this.vertexData[j+2]= (float)coordinates[i].z; 3852 } 3853 if(isLive) { 3854 geomLock.unLock(); 3855 } 3856 3857 if (inUpdater ||source == null ) { 3858 return; 3859 } 3860 if (!isLive) { 3861 boundsDirty = true; 3862 return; 3863 } 3864 3865 // Compute geo's bounds 3866 processCoordsChanged(false); 3867 3868 sendDataChangedMessage(true); 3869 } 3870 3871 3872 /** 3873 * Sets the coordinates associated with the vertices starting at 3874 * the specified index for this object using coordinate data starting 3875 * from vertex index <code>start</code> for <code>length</code> vertices. 3876 * @param index the vertex index 3877 * @param coordinates an array of vectors containing new coordinates 3878 * @param start starting vertex index of data in <code>coordinates</code> . 3879 * @param length number of vertices to be copied. 3880 */ setCoordinates(int index, float coordinates[], int start, int length)3881 void setCoordinates(int index, float coordinates[], int start, int length) { 3882 int offset = this.stride * index + coordinateOffset; 3883 int i, j; 3884 boolean isLive = source!=null && source.isLive(); 3885 if(isLive){ 3886 geomLock.getLock(); 3887 } 3888 dirtyFlag |= COORDINATE_CHANGED; 3889 for (i= start * 3, j= offset; i < (start+length) * 3; 3890 i+=3, j+= this.stride) { 3891 this.vertexData[j] = coordinates[i]; 3892 this.vertexData[j+1]= coordinates[i+1]; 3893 this.vertexData[j+2]= coordinates[i+2]; 3894 } 3895 if(isLive) { 3896 geomLock.unLock(); 3897 } 3898 if (inUpdater ||source == null ) { 3899 return; 3900 } 3901 if (!isLive) { 3902 boundsDirty = true; 3903 return; 3904 } 3905 3906 // Compute geo's bounds 3907 processCoordsChanged(false); 3908 3909 sendDataChangedMessage(true); 3910 } 3911 3912 /** 3913 * Sets the coordinates associated with the vertices starting at 3914 * the specified index for this object using coordinate data starting 3915 * from vertex index <code>start</code> for <code>length</code> vertices. 3916 * @param index the vertex index 3917 * @param coordinates an array of 3*n values containing n new coordinates 3918 * @param start starting vertex index of data in <code>coordinates</code> . 3919 * @param length number of vertices to be copied. 3920 */ setCoordinates(int index, double coordinates[], int start, int length)3921 void setCoordinates(int index, double coordinates[], int start, int length) { 3922 int offset = this.stride * index + coordinateOffset; 3923 int i, j; 3924 boolean isLive = source!=null && source.isLive(); 3925 if(isLive){ 3926 geomLock.getLock(); 3927 } 3928 dirtyFlag |= COORDINATE_CHANGED; 3929 3930 for (i= start*3, j= offset; i < (start+length)*3; 3931 i+=3, j+= this.stride) { 3932 this.vertexData[j] = (float)coordinates[i]; 3933 this.vertexData[j+1]= (float)coordinates[i+1]; 3934 this.vertexData[j+2]= (float)coordinates[i+2]; 3935 } 3936 3937 if(isLive) { 3938 geomLock.unLock(); 3939 } 3940 if (inUpdater || (source == null)) { 3941 return; 3942 } 3943 if (!isLive) { 3944 boundsDirty = true; 3945 return; 3946 } 3947 3948 3949 // Compute geo's bounds 3950 processCoordsChanged(false); 3951 3952 sendDataChangedMessage(true); 3953 } 3954 3955 /** 3956 * Sets the coordinates associated with the vertices starting at 3957 * the specified index for this object using coordinate data starting 3958 * from vertex index <code>start</code> for <code>length</code> vertices. 3959 * @param index the vertex index 3960 * @param coordinates an array of vectors containing new coordinates 3961 * @param start starting vertex index of data in <code>coordinates</code> . 3962 * @param length number of vertices to be copied. 3963 */ setCoordinates(int index, Point3f coordinates[], int start, int length)3964 void setCoordinates(int index, Point3f coordinates[], int start, 3965 int length) { 3966 int offset = this.stride * index + coordinateOffset; 3967 int i, j; 3968 boolean isLive = source!=null && source.isLive(); 3969 if(isLive){ 3970 geomLock.getLock(); 3971 } 3972 dirtyFlag |= COORDINATE_CHANGED; 3973 3974 for (i=start, j= offset;i < start + length; i++, j+= this.stride) { 3975 this.vertexData[j] = coordinates[i].x; 3976 this.vertexData[j+1]= coordinates[i].y; 3977 this.vertexData[j+2]= coordinates[i].z; 3978 } 3979 3980 if(isLive) { 3981 geomLock.unLock(); 3982 } 3983 3984 if (inUpdater || (source == null)) { 3985 return; 3986 } 3987 if (!isLive) { 3988 boundsDirty = true; 3989 return; 3990 } 3991 3992 3993 // Compute geo's bounds 3994 processCoordsChanged(false); 3995 3996 sendDataChangedMessage(true); 3997 } 3998 3999 /** 4000 * Sets the coordinates associated with the vertices starting at 4001 * the specified index for this object using coordinate data starting 4002 * from vertex index <code>start</code> for <code>length</code> vertices. 4003 * @param index the vertex index 4004 * @param coordinates an array of vectors containing new coordinates 4005 * @param start starting vertex index of data in <code>coordinates</code> . 4006 * @param length number of vertices to be copied. 4007 */ setCoordinates(int index, Point3d coordinates[], int start, int length)4008 void setCoordinates(int index, Point3d coordinates[], int start, 4009 int length) { 4010 int offset = this.stride * index + coordinateOffset; 4011 int i, j; 4012 boolean isLive = source!=null && source.isLive(); 4013 if(isLive){ 4014 geomLock.getLock(); 4015 } 4016 dirtyFlag |= COORDINATE_CHANGED; 4017 4018 for (i=start, j= offset;i < start + length; i++, j+= this.stride) { 4019 this.vertexData[j] = (float)coordinates[i].x; 4020 this.vertexData[j+1]= (float)coordinates[i].y; 4021 this.vertexData[j+2]= (float)coordinates[i].z; 4022 } 4023 4024 if(isLive) { 4025 geomLock.unLock(); 4026 } 4027 if (inUpdater || (source == null)) { 4028 return; 4029 } 4030 if (!isLive) { 4031 boundsDirty = true; 4032 return; 4033 } 4034 4035 // Compute geo's bounds 4036 processCoordsChanged(false); 4037 4038 sendDataChangedMessage(true); 4039 } 4040 4041 /** 4042 * Sets the color associated with the vertex at 4043 * the specified index. 4044 * @param index the vertex index 4045 * @param color an array of 3 or 4 values containing the new color 4046 */ setColor(int index, float color[])4047 void setColor(int index, float color[]) { 4048 int offset = this.stride*index + colorOffset; 4049 4050 boolean isLive = source!=null && source.isLive(); 4051 if(isLive){ 4052 geomLock.getLock(); 4053 } 4054 dirtyFlag |= COLOR_CHANGED; 4055 colorChanged = 0xffff; 4056 this.vertexData[offset] = color[0]; 4057 this.vertexData[offset+1] = color[1]; 4058 this.vertexData[offset+2] = color[2]; 4059 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 4060 this.vertexData[offset+3] = color[3]*lastAlpha[0]; 4061 else 4062 this.vertexData[offset+3] = lastAlpha[0]; 4063 4064 if(isLive) { 4065 geomLock.unLock(); 4066 sendDataChangedMessage(false); 4067 } 4068 4069 } 4070 4071 /** 4072 * Sets the color associated with the vertex at 4073 * the specified index. 4074 * @param index the vertex index 4075 * @param color an array of 3 or 4 values containing the new color 4076 */ setColor(int index, byte color[])4077 void setColor(int index, byte color[]) { 4078 int offset = this.stride*index + colorOffset; 4079 4080 boolean isLive = source!=null && source.isLive(); 4081 if(isLive) { 4082 geomLock.getLock(); 4083 } 4084 4085 dirtyFlag |= COLOR_CHANGED; 4086 colorChanged = 0xffff; 4087 this.vertexData[offset] = (color[0] & 0xff) * ByteToFloatScale; 4088 this.vertexData[offset+1] = (color[1] & 0xff) * ByteToFloatScale; 4089 this.vertexData[offset+2] = (color[2] & 0xff) * ByteToFloatScale; 4090 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 4091 this.vertexData[offset+3] = ((color[3] & 0xff)* ByteToFloatScale)*lastAlpha[0]; 4092 else 4093 this.vertexData[offset+3] = lastAlpha[0]; 4094 4095 if(isLive) { 4096 geomLock.unLock(); 4097 sendDataChangedMessage(false); 4098 } 4099 4100 } 4101 4102 /** 4103 * Sets the color associated with the vertex at 4104 * the specified index. 4105 * @param index the vertex index 4106 * @param color a vector containing the new color 4107 */ setColor(int index, Color3f color)4108 void setColor(int index, Color3f color) { 4109 int offset = this.stride*index + colorOffset; 4110 4111 boolean isLive = source!=null && source.isLive(); 4112 if(isLive){ 4113 geomLock.getLock(); 4114 } 4115 4116 dirtyFlag |= COLOR_CHANGED; 4117 colorChanged = 0xffff; 4118 this.vertexData[offset] = color.x; 4119 this.vertexData[offset+1] = color.y; 4120 this.vertexData[offset+2] = color.z; 4121 this.vertexData[offset+3] = lastAlpha[0]; 4122 4123 if(isLive) { 4124 geomLock.unLock(); 4125 sendDataChangedMessage(false); 4126 } 4127 4128 4129 } 4130 4131 /** 4132 * Sets the color associated with the vertex at 4133 * the specified index. 4134 * @param index the vertex index 4135 * @param color a vector containing the new color 4136 */ setColor(int index, Color4f color)4137 void setColor(int index, Color4f color) { 4138 int offset = this.stride*index + colorOffset; 4139 boolean isLive = source!=null && source.isLive(); 4140 if(isLive){ 4141 geomLock.getLock(); 4142 } 4143 dirtyFlag |= COLOR_CHANGED; 4144 colorChanged = 0xffff; 4145 this.vertexData[offset] = color.x; 4146 this.vertexData[offset+1] = color.y; 4147 this.vertexData[offset+2] = color.z; 4148 this.vertexData[offset+3] = color.w*lastAlpha[0]; 4149 4150 if(isLive) { 4151 geomLock.unLock(); 4152 sendDataChangedMessage(false); 4153 } 4154 4155 } 4156 4157 /** 4158 * Sets the color associated with the vertex at 4159 * the specified index. 4160 * @param index the vertex index 4161 * @param color a vector containing the new color 4162 */ setColor(int index, Color3b color)4163 void setColor(int index, Color3b color) { 4164 int offset = this.stride*index + colorOffset; 4165 4166 boolean isLive = source!=null && source.isLive(); 4167 if(isLive){ 4168 geomLock.getLock(); 4169 } 4170 4171 dirtyFlag |= COLOR_CHANGED; 4172 colorChanged = 0xffff; 4173 this.vertexData[offset] = (color.x & 0xff) * ByteToFloatScale; 4174 this.vertexData[offset+1] = (color.y & 0xff) * ByteToFloatScale; 4175 this.vertexData[offset+2] = (color.z & 0xff) * ByteToFloatScale; 4176 this.vertexData[offset+3] = lastAlpha[0]; 4177 4178 if(isLive) { 4179 geomLock.unLock(); 4180 sendDataChangedMessage(false); 4181 } 4182 4183 } 4184 4185 /** 4186 * Sets the color associated with the vertex at 4187 * the specified index. 4188 * @param index the vertex index 4189 * @param color a vector containing the new color 4190 */ setColor(int index, Color4b color)4191 void setColor(int index, Color4b color) { 4192 int offset = this.stride*index + colorOffset; 4193 4194 boolean isLive = source!=null && source.isLive(); 4195 if(isLive){ 4196 geomLock.getLock(); 4197 } 4198 dirtyFlag |= COLOR_CHANGED; 4199 colorChanged = 0xffff; 4200 this.vertexData[offset] = (color.x * 0xff) * ByteToFloatScale; 4201 this.vertexData[offset+1] = (color.y * 0xff) * ByteToFloatScale; 4202 this.vertexData[offset+2] = (color.z * 0xff) * ByteToFloatScale; 4203 this.vertexData[offset+3] = ((color.w & 0xff) * ByteToFloatScale)*lastAlpha[0]; 4204 4205 if(isLive){ 4206 geomLock.unLock(); 4207 sendDataChangedMessage(false); 4208 } 4209 4210 } 4211 4212 /** 4213 * Sets the colors associated with the vertices starting at 4214 * the specified index. 4215 * @param index the vertex index 4216 * @param colors an array of 3*n or 4*n values containing n new colors 4217 */ setColors(int index, float colors[])4218 void setColors(int index, float colors[]) { 4219 int offset = this.stride*index + colorOffset; 4220 int i, j, num = colors.length; 4221 4222 boolean isLive = source!=null && source.isLive(); 4223 if(isLive){ 4224 geomLock.getLock(); 4225 } 4226 dirtyFlag |= COLOR_CHANGED; 4227 colorChanged = 0xffff; 4228 4229 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 4230 { 4231 for (i=0, j= offset;i < num; i+= 4, j+= this.stride) 4232 { 4233 this.vertexData[j] = colors[i]; 4234 this.vertexData[j+1] = colors[i+1]; 4235 this.vertexData[j+2] = colors[i+2]; 4236 this.vertexData[j+3] = colors[i+3]*lastAlpha[0]; 4237 } 4238 } 4239 else 4240 { 4241 for (i=0, j= offset;i < num; i+= 3, j+= this.stride) 4242 { 4243 this.vertexData[j] = colors[i]; 4244 this.vertexData[j+1] = colors[i+1]; 4245 this.vertexData[j+2] = colors[i+2]; 4246 this.vertexData[j+3] = lastAlpha[0]; 4247 } 4248 } 4249 4250 if(isLive) { 4251 geomLock.unLock(); 4252 sendDataChangedMessage(false); 4253 } 4254 4255 } 4256 4257 /** 4258 * Sets the colors associated with the vertices starting at 4259 * the specified index. 4260 * @param index the vertex index 4261 * @param colors an array of 3*n or 4*n values containing n new colors 4262 */ setColors(int index, byte colors[])4263 void setColors(int index, byte colors[]) { 4264 int offset = this.stride*index + colorOffset; 4265 int i, j, num = colors.length; 4266 4267 boolean isLive = source!=null && source.isLive(); 4268 if(isLive){ 4269 geomLock.getLock(); 4270 } 4271 dirtyFlag |= COLOR_CHANGED; 4272 colorChanged = 0xffff; 4273 4274 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 4275 { 4276 for (i=0, j= offset;i < num; i+= 4, j+= this.stride) 4277 { 4278 this.vertexData[j] = (colors[i] & 0xff) * ByteToFloatScale; 4279 this.vertexData[j+1] = (colors[i+1] & 0xff) * ByteToFloatScale; 4280 this.vertexData[j+2] = (colors[i+2] & 0xff) * ByteToFloatScale; 4281 this.vertexData[j+3] = ((colors[i+3] & 0xff) * ByteToFloatScale)*lastAlpha[0]; 4282 } 4283 } 4284 else 4285 { 4286 for (i=0, j= offset;i < num; i+= 3, j+= this.stride) 4287 { 4288 this.vertexData[j] = (colors[i] & 0xff) * ByteToFloatScale; 4289 this.vertexData[j+1] = (colors[i+1] & 0xff) * ByteToFloatScale; 4290 this.vertexData[j+2] = (colors[i+2] & 0xff) * ByteToFloatScale; 4291 this.vertexData[j+3] = lastAlpha[0]; 4292 } 4293 } 4294 4295 4296 if(isLive) { 4297 geomLock.unLock(); 4298 sendDataChangedMessage(false); 4299 } 4300 4301 } 4302 4303 /** 4304 * Sets the colors associated with the vertices starting at 4305 * the specified index. 4306 * @param index the vertex index 4307 * @param colors an array of vectors containing new colors 4308 */ setColors(int index, Color3f colors[])4309 void setColors(int index, Color3f colors[]) { 4310 int offset = this.stride*index + colorOffset; 4311 int i, j, num = colors.length; 4312 4313 boolean isLive = source!=null && source.isLive(); 4314 if(isLive){ 4315 geomLock.getLock(); 4316 } 4317 dirtyFlag |= COLOR_CHANGED; 4318 colorChanged = 0xffff; 4319 4320 for (i=0, j= offset;i < num; i++, j+= this.stride) 4321 { 4322 this.vertexData[j] = colors[i].x; 4323 this.vertexData[j+1] = colors[i].y; 4324 this.vertexData[j+2] = colors[i].z; 4325 this.vertexData[j+3] = lastAlpha[0]; 4326 } 4327 if(isLive) { 4328 geomLock.unLock(); 4329 sendDataChangedMessage(false); 4330 } 4331 4332 } 4333 4334 /** 4335 * Sets the colors associated with the vertices starting at 4336 * the specified index. 4337 * @param index the vertex index 4338 * @param colors an array of vectors containing new colors 4339 */ setColors(int index, Color4f colors[])4340 void setColors(int index, Color4f colors[]) { 4341 int offset = this.stride*index + colorOffset; 4342 int i, j, num = colors.length; 4343 boolean isLive = source!=null && source.isLive(); 4344 if(isLive){ 4345 geomLock.getLock(); 4346 } 4347 dirtyFlag |= COLOR_CHANGED; 4348 colorChanged = 0xffff; 4349 4350 for (i=0, j= offset;i < num; i++, j+= this.stride) 4351 { 4352 this.vertexData[j] = colors[i].x; 4353 this.vertexData[j+1] = colors[i].y; 4354 this.vertexData[j+2] = colors[i].z; 4355 this.vertexData[j+3] = colors[i].w*lastAlpha[0]; 4356 } 4357 if(isLive) { 4358 geomLock.unLock(); 4359 sendDataChangedMessage(false); 4360 } 4361 4362 } 4363 4364 /** 4365 * Sets the colors associated with the vertices starting at 4366 * the specified index. 4367 * @param index the vertex index 4368 * @param colors an array of vectors containing new colors 4369 */ setColors(int index, Color3b colors[])4370 void setColors(int index, Color3b colors[]) { 4371 int offset = this.stride*index + colorOffset; 4372 int i, j, num = colors.length; 4373 boolean isLive = source!=null && source.isLive(); 4374 if(isLive){ 4375 geomLock.getLock(); 4376 } 4377 dirtyFlag |= COLOR_CHANGED; 4378 colorChanged = 0xffff; 4379 for (i=0, j= offset;i < num; i++, j+= this.stride) 4380 { 4381 this.vertexData[j] = (colors[i].x & 0xff) * ByteToFloatScale; 4382 this.vertexData[j+1] = (colors[i].y & 0xff) * ByteToFloatScale; 4383 this.vertexData[j+2] = (colors[i].z & 0xff) * ByteToFloatScale; 4384 this.vertexData[j+3] = lastAlpha[0]; 4385 } 4386 4387 if(isLive) { 4388 geomLock.unLock(); 4389 sendDataChangedMessage(false); 4390 } 4391 } 4392 4393 4394 /** 4395 * Sets the colors associated with the vertices starting at 4396 * the specified index. 4397 * @param index the vertex index 4398 * @param colors an array of vectors containing new colors 4399 */ setColors(int index, Color4b colors[])4400 void setColors(int index, Color4b colors[]) { 4401 int offset = this.stride*index + colorOffset; 4402 int i, j, num = colors.length; 4403 4404 boolean isLive = source!=null && source.isLive(); 4405 if(isLive){ 4406 geomLock.getLock(); 4407 } 4408 dirtyFlag |= COLOR_CHANGED; 4409 colorChanged = 0xffff; 4410 4411 for (i=0, j= offset;i < num; i++, j+= this.stride) 4412 { 4413 this.vertexData[j] = (colors[i].x & 0xff) * ByteToFloatScale; 4414 this.vertexData[j+1] = (colors[i].y & 0xff) * ByteToFloatScale; 4415 this.vertexData[j+2] = (colors[i].z & 0xff) * ByteToFloatScale; 4416 this.vertexData[j+3] = ((colors[i].w & 0xff) * ByteToFloatScale)*lastAlpha[0]; 4417 } 4418 4419 if(isLive) { 4420 geomLock.unLock(); 4421 sendDataChangedMessage(false); 4422 } 4423 4424 } 4425 4426 /** 4427 * Sets the colors associated with the vertices starting at 4428 * the specified index for this object using data in <code>color</code>s 4429 * starting at index <code>start</code> for <code>length</code> colors. 4430 * @param index the vertex index 4431 * @param colors an array of 3*n or 4*n values containing n new colors 4432 * @param start starting color index of data in <code>colors</code>. 4433 * @param length number of colors to be copied. 4434 */ setColors(int index, float colors[], int start, int length)4435 void setColors(int index, float colors[], int start, int length) { 4436 int offset = this.stride*index + colorOffset; 4437 int i, j; 4438 boolean isLive = source!=null && source.isLive(); 4439 if(isLive){ 4440 geomLock.getLock(); 4441 } 4442 dirtyFlag |= COLOR_CHANGED; 4443 colorChanged = 0xffff; 4444 4445 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) { 4446 for (i = start * 4, j = offset; i < (start + length) * 4; 4447 i += 4, j += this.stride) { 4448 this.vertexData[j] = colors[i]; 4449 this.vertexData[j+1] = colors[i+1]; 4450 this.vertexData[j+2] = colors[i+2]; 4451 this.vertexData[j+3] = colors[i+3]*lastAlpha[0]; 4452 } 4453 } else { 4454 for (i = start * 3, j = offset; i < (start + length) * 3; 4455 i += 3, j += this.stride) { 4456 this.vertexData[j] = colors[i]; 4457 this.vertexData[j+1] = colors[i+1]; 4458 this.vertexData[j+2] = colors[i+2]; 4459 this.vertexData[j+3] = lastAlpha[0]; 4460 } 4461 } 4462 4463 if(isLive) { 4464 geomLock.unLock(); 4465 sendDataChangedMessage(false); 4466 } 4467 4468 } 4469 4470 /** 4471 * Sets the colors associated with the vertices starting at 4472 * the specified index for this object using data in <code>color</code>s 4473 * starting at index <code>start</code> for <code>length</code> colors. 4474 * @param index the vertex index 4475 * @param colors an array of 3*n or 4*n values containing n new colors 4476 * @param start starting color index of data in <code>colors</code>. 4477 * @param length number of colors to be copied. 4478 */ setColors(int index, byte colors[], int start, int length)4479 void setColors(int index, byte colors[], int start, int length) { 4480 int offset = this.stride*index + colorOffset; 4481 int i, j; 4482 4483 boolean isLive = source!=null && source.isLive(); 4484 if(isLive){ 4485 geomLock.getLock(); 4486 } 4487 dirtyFlag |= COLOR_CHANGED; 4488 colorChanged = 0xffff; 4489 4490 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) { 4491 for (i = start * 4, j = offset; i < (start + length) * 4; 4492 i += 4, j += this.stride) { 4493 this.vertexData[j] = (colors[i] & 0xff) * ByteToFloatScale; 4494 this.vertexData[j+1] = (colors[i+1] & 0xff) * ByteToFloatScale; 4495 this.vertexData[j+2] = (colors[i+2] & 0xff) * ByteToFloatScale; 4496 this.vertexData[j+3] = ((colors[i+3] & 0xff) * ByteToFloatScale)*lastAlpha[0]; 4497 } 4498 } else { 4499 for (i = start * 3, j = offset; i < (start + length) * 3; 4500 i += 3, j += this.stride) { 4501 this.vertexData[j] = (colors[i] & 0xff) * ByteToFloatScale; 4502 this.vertexData[j+1] = (colors[i+1] & 0xff) * ByteToFloatScale; 4503 this.vertexData[j+2] = (colors[i+2] & 0xff) * ByteToFloatScale; 4504 this.vertexData[j+3] = lastAlpha[0]; 4505 } 4506 } 4507 4508 if(isLive) { 4509 geomLock.unLock(); 4510 sendDataChangedMessage(false); 4511 } 4512 4513 } 4514 4515 /** 4516 * Sets the colors associated with the vertices starting at 4517 * the specified index for this object using data in <code>color</code>s 4518 * starting at index <code>start</code> for <code>length</code> colors. 4519 * @param index the vertex index 4520 * @param colors an array of 3*n or 4*n values containing n new colors 4521 * @param start starting color index of data in <code>colors</code>. 4522 * @param length number of colors to be copied. 4523 */ setColors(int index, Color3f colors[], int start, int length)4524 void setColors(int index, Color3f colors[], int start, int length) { 4525 int offset = this.stride*index + colorOffset; 4526 int i, j; 4527 boolean isLive = source!=null && source.isLive(); 4528 if(isLive){ 4529 geomLock.getLock(); 4530 } 4531 dirtyFlag |= COLOR_CHANGED; 4532 colorChanged = 0xffff; 4533 4534 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4535 this.vertexData[j] = colors[i].x; 4536 this.vertexData[j+1] = colors[i].y; 4537 this.vertexData[j+2] = colors[i].z; 4538 this.vertexData[j+3] = lastAlpha[0]; 4539 } 4540 4541 if(isLive) { 4542 geomLock.unLock(); 4543 sendDataChangedMessage(false); 4544 } 4545 4546 } 4547 4548 /** 4549 * Sets the colors associated with the vertices starting at 4550 * the specified index for this object using data in <code>color</code>s 4551 * starting at index <code>start</code> for <code>length</code> colors. 4552 * @param index the vertex index 4553 * @param colors an array of 3*n or 4*n values containing n new colors 4554 * @param start starting color index of data in <code>colors</code>. 4555 * @param length number of colors to be copied. 4556 */ setColors(int index, Color4f colors[], int start, int length)4557 void setColors(int index, Color4f colors[], int start, int length) { 4558 int offset = this.stride*index + colorOffset; 4559 int i, j; 4560 boolean isLive = source!=null && source.isLive(); 4561 if(isLive){ 4562 geomLock.getLock(); 4563 } 4564 dirtyFlag |= COLOR_CHANGED; 4565 colorChanged = 0xffff; 4566 4567 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4568 this.vertexData[j] = colors[i].x; 4569 this.vertexData[j+1] = colors[i].y; 4570 this.vertexData[j+2] = colors[i].z; 4571 this.vertexData[j+3] = colors[i].w*lastAlpha[0]; 4572 } 4573 4574 if(isLive) { 4575 geomLock.unLock(); 4576 sendDataChangedMessage(false); 4577 } 4578 4579 } 4580 4581 /** 4582 * Sets the colors associated with the vertices starting at 4583 * the specified index for this object using data in <code>color</code>s 4584 * starting at index <code>start</code> for <code>length</code> colors. 4585 * @param index the vertex index 4586 * @param colors an array of 3*n or 4*n values containing n new colors 4587 * @param start starting color index of data in <code>colors</code>. 4588 * @param length number of colors to be copied. 4589 */ setColors(int index, Color3b colors[], int start, int length)4590 void setColors(int index, Color3b colors[], int start, int length) { 4591 int offset = this.stride*index + colorOffset; 4592 int i, j; 4593 boolean isLive = source!=null && source.isLive(); 4594 if(isLive){ 4595 geomLock.getLock(); 4596 } 4597 dirtyFlag |= COLOR_CHANGED; 4598 colorChanged = 0xffff; 4599 4600 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4601 this.vertexData[j] = (colors[i].x & 0xff) * ByteToFloatScale; 4602 this.vertexData[j+1] = (colors[i].y & 0xff) * ByteToFloatScale; 4603 this.vertexData[j+2] = (colors[i].z & 0xff) * ByteToFloatScale; 4604 this.vertexData[j+3] = lastAlpha[0]; 4605 } 4606 4607 if(isLive) { 4608 geomLock.unLock(); 4609 sendDataChangedMessage(false); 4610 } 4611 4612 } 4613 4614 /** 4615 * Sets the colors associated with the vertices starting at 4616 * the specified index for this object using data in <code>color</code>s 4617 * starting at index <code>start</code> for <code>length</code> colors. 4618 * @param index the vertex index 4619 * @param colors an array of 3*n or 4*n values containing n new colors 4620 * @param start starting color index of data in <code>colors</code>. 4621 * @param length number of colors to be copied. 4622 */ setColors(int index, Color4b colors[], int start, int length)4623 void setColors(int index, Color4b colors[], int start, int length) { 4624 int offset = this.stride*index + colorOffset; 4625 int i, j; 4626 boolean isLive = source!=null && source.isLive(); 4627 if(isLive){ 4628 geomLock.getLock(); 4629 } 4630 dirtyFlag |= COLOR_CHANGED; 4631 colorChanged = 0xffff; 4632 4633 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4634 this.vertexData[j] = (colors[i].x & 0xff) * ByteToFloatScale; 4635 this.vertexData[j+1] = (colors[i].y & 0xff) * ByteToFloatScale; 4636 this.vertexData[j+2] = (colors[i].z & 0xff) * ByteToFloatScale; 4637 this.vertexData[j+3] = ((colors[i].w & 0xff) * ByteToFloatScale)*lastAlpha[0]; 4638 } 4639 4640 if(isLive) { 4641 geomLock.unLock(); 4642 sendDataChangedMessage(false); 4643 } 4644 4645 } 4646 4647 /** 4648 * Sets the normal associated with the vertex at 4649 * the specified index. 4650 * @param index the vertex index 4651 * @param normal the new normal 4652 */ setNormal(int index, float normal[])4653 void setNormal(int index, float normal[]) { 4654 int offset = this.stride*index + normalOffset; 4655 boolean isLive = source!=null && source.isLive(); 4656 if(isLive){ 4657 geomLock.getLock(); 4658 } 4659 this.vertexData[offset] = normal[0]; 4660 this.vertexData[offset+1] = normal[1]; 4661 this.vertexData[offset+2] = normal[2]; 4662 4663 if(isLive) { 4664 geomLock.unLock(); 4665 sendDataChangedMessage(false); 4666 } 4667 4668 } 4669 4670 /** 4671 * Sets the normal associated with the vertex at 4672 * the specified index. 4673 * @param index the vertex index 4674 * @param normal the vector containing the new normal 4675 */ setNormal(int index, Vector3f normal)4676 void setNormal(int index, Vector3f normal) { 4677 int offset = this.stride*index + normalOffset; 4678 boolean isLive = source!=null && source.isLive(); 4679 if(isLive){ 4680 geomLock.getLock(); 4681 } 4682 dirtyFlag |= NORMAL_CHANGED; 4683 this.vertexData[offset] = normal.x; 4684 this.vertexData[offset+1] = normal.y; 4685 this.vertexData[offset+2] = normal.z; 4686 4687 if(isLive){ 4688 geomLock.unLock(); 4689 sendDataChangedMessage(false); 4690 } 4691 4692 } 4693 4694 /** 4695 * Sets the normals associated with the vertices starting at 4696 * the specified index. 4697 * @param index the vertex index 4698 * @param normals the new normals 4699 */ setNormals(int index, float normals[])4700 void setNormals(int index, float normals[]) { 4701 int offset = this.stride*index + normalOffset; 4702 int i, j, num = normals.length; 4703 boolean isLive = source!=null && source.isLive(); 4704 if(isLive){ 4705 geomLock.getLock(); 4706 } 4707 dirtyFlag |= NORMAL_CHANGED; 4708 for (i=0, j= offset;i < num;i += 3, j+= this.stride) 4709 { 4710 this.vertexData[j] = normals[i]; 4711 this.vertexData[j+1] = normals[i+1]; 4712 this.vertexData[j+2] = normals[i+2]; 4713 } 4714 if(isLive) { 4715 geomLock.unLock(); 4716 sendDataChangedMessage(false); 4717 } 4718 4719 } 4720 4721 /** 4722 * Sets the normals associated with the vertices starting at 4723 * the specified index. 4724 * @param index the vertex index 4725 * @param normals the vector containing the new normals 4726 */ setNormals(int index, Vector3f normals[])4727 void setNormals(int index, Vector3f normals[]) { 4728 int offset = this.stride*index + normalOffset; 4729 int i, j, num = normals.length; 4730 boolean isLive = source!=null && source.isLive(); 4731 if(isLive){ 4732 geomLock.getLock(); 4733 } 4734 dirtyFlag |= NORMAL_CHANGED; 4735 for (i=0, j= offset;i < num;i++, j+= this.stride) 4736 { 4737 this.vertexData[j] = normals[i].x; 4738 this.vertexData[j+1] = normals[i].y; 4739 this.vertexData[j+2] = normals[i].z; 4740 } 4741 if(isLive) { 4742 geomLock.unLock(); 4743 sendDataChangedMessage(false); 4744 } 4745 4746 } 4747 4748 /** 4749 * Sets the normals associated with the vertices starting at 4750 * the specified index for this object using data in <code>normals</code> 4751 * starting at index <code>start</code> and ending at index <code>start+length</code>. 4752 * @param index the vertex index 4753 * @param normals the new normals 4754 * @param start starting normal index of data in <code>colors</code> . 4755 * @param length number of normals to be copied. 4756 */ setNormals(int index, float normals[], int start, int length)4757 void setNormals(int index, float normals[], int start, int length) { 4758 int offset = this.stride*index + normalOffset; 4759 int i, j; 4760 boolean isLive = source!=null && source.isLive(); 4761 if(isLive){ 4762 geomLock.getLock(); 4763 } 4764 dirtyFlag |= NORMAL_CHANGED; 4765 for (i = start * 3, j = offset; i < (start + length) * 3; 4766 i+=3, j += this.stride) { 4767 this.vertexData[j] = normals[i]; 4768 this.vertexData[j+1] = normals[i+1]; 4769 this.vertexData[j+2] = normals[i+2]; 4770 } 4771 if(isLive) { 4772 geomLock.unLock(); 4773 sendDataChangedMessage(false); 4774 } 4775 4776 } 4777 4778 /** 4779 * Sets the normals associated with the vertices starting at 4780 * the specified index for this object using data in <code>normals</code> 4781 * starting at index <code>start</code> and ending at index <code>start+length</code>. 4782 * @param index the vertex index 4783 * @param normals the new normals 4784 * @param start starting normal index of data in <code>colors</code> . 4785 * @param length number of normals to be copied. 4786 */ setNormals(int index, Vector3f normals[], int start, int length)4787 void setNormals(int index, Vector3f normals[], int start, int length) { 4788 int offset = this.stride*index + normalOffset; 4789 int i, j; 4790 boolean isLive = source!=null && source.isLive(); 4791 if(isLive){ 4792 geomLock.getLock(); 4793 } 4794 dirtyFlag |= NORMAL_CHANGED; 4795 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4796 this.vertexData[j] = normals[i].x; 4797 this.vertexData[j+1] = normals[i].y; 4798 this.vertexData[j+2] = normals[i].z; 4799 } 4800 if(isLive) { 4801 geomLock.unLock(); 4802 sendDataChangedMessage(false); 4803 } 4804 4805 } 4806 4807 4808 /** 4809 * Sets the texture coordinates associated with the vertices starting at 4810 * the specified index for this object using data in <code>texCoords</code> 4811 * starting at index <code>start</code> and ending at index <code>start+length</code>. 4812 * @param index the vertex index 4813 * @param texCoords the new texture coordinates 4814 * @param start starting texture coordinate index of data in <code>texCoords</code> . 4815 * @param length number of texture Coordinates to be copied. 4816 */ setTextureCoordinates(int texCoordSet, int index, float texCoords[], int start, int length)4817 void setTextureCoordinates(int texCoordSet, int index, float texCoords[], 4818 int start, int length) { 4819 4820 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) != 0) 4821 throw new IllegalStateException(J3dI18N.getString("GeometryArray82")); 4822 4823 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE ) == 0) 4824 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray79")); 4825 4826 int offset = this.stride*index + textureOffset + 4827 texCoordSet * texCoordStride; 4828 int i, j, k; 4829 boolean isLive = source!=null && source.isLive(); 4830 if(isLive){ 4831 geomLock.getLock(); 4832 } 4833 dirtyFlag |= TEXTURE_CHANGED; 4834 4835 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 4836 for (i = start * 4, j = offset, k = 0; k < length; 4837 j += this.stride, k++) { 4838 this.vertexData[j] = texCoords[i++]; 4839 this.vertexData[j+1] = texCoords[i++]; 4840 this.vertexData[j+2] = texCoords[i++]; 4841 this.vertexData[j+3] = texCoords[i++]; 4842 } 4843 } else if ((this.vertexFormat & 4844 GeometryArray.TEXTURE_COORDINATE_3) != 0) { 4845 for (i = start * 3, j = offset, k = 0; k < length; 4846 j += this.stride, k++) { 4847 this.vertexData[j] = texCoords[i++]; 4848 this.vertexData[j+1] = texCoords[i++]; 4849 this.vertexData[j+2] = texCoords[i++]; 4850 } 4851 } else { 4852 for (i = start * 2, j = offset, k = 0; k < length; 4853 j += this.stride, k++) { 4854 this.vertexData[j] = texCoords[i++]; 4855 this.vertexData[j+1] = texCoords[i++]; 4856 } 4857 } 4858 if(isLive) { 4859 geomLock.unLock(); 4860 sendDataChangedMessage(false); 4861 } 4862 4863 } 4864 4865 /** 4866 * Sets the texture coordinates associated with the vertices starting at 4867 * the specified index for this object using data in <code>texCoords</code> 4868 * starting at index <code>start</code> and ending at index <code>start+length</code>. 4869 * @param index the vertex index 4870 * @param texCoords the new texture coordinates 4871 * @param start starting texture coordinate index of data in <code>texCoords</code> . 4872 * @param length number of texture Coordinates to be copied. 4873 */ setTextureCoordinates(int texCoordSet, int index, Point2f texCoords[], int start, int length)4874 void setTextureCoordinates(int texCoordSet, int index, Point2f texCoords[], 4875 int start, int length) { 4876 4877 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) != 0) 4878 throw new IllegalStateException(J3dI18N.getString("GeometryArray82")); 4879 4880 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE ) == 0) 4881 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray79")); 4882 4883 int offset = this.stride*index + textureOffset + 4884 texCoordSet * texCoordStride; 4885 int i, j; 4886 4887 boolean isLive = source!=null && source.isLive(); 4888 if(isLive){ 4889 geomLock.getLock(); 4890 } 4891 dirtyFlag |= TEXTURE_CHANGED; 4892 4893 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4894 this.vertexData[j] = texCoords[i].x; 4895 this.vertexData[j+1] = texCoords[i].y; 4896 } 4897 if(isLive) { 4898 geomLock.unLock(); 4899 sendDataChangedMessage(false); 4900 } 4901 4902 } 4903 4904 /** 4905 * Sets the texture coordinates associated with the vertices starting at 4906 * the specified index for this object using data in <code>texCoords</code> 4907 * starting at index <code>start</code> and ending at index <code>start+length</code>. 4908 * @param index the vertex index 4909 * @param texCoords the new texture coordinates 4910 * @param start starting texture coordinate index of data in <code>texCoords</code> . 4911 * @param length number of texture Coordinates to be copied. 4912 */ setTextureCoordinates(int texCoordSet, int index, Point3f texCoords[], int start, int length)4913 void setTextureCoordinates(int texCoordSet, int index, Point3f texCoords[], 4914 int start, int length) { 4915 4916 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) != 0) 4917 throw new IllegalStateException(J3dI18N.getString("GeometryArray82")); 4918 4919 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE ) == 0) 4920 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray79")); 4921 4922 int offset = this.stride*index + textureOffset + 4923 texCoordSet * texCoordStride; 4924 int i, j; 4925 boolean isLive = source!=null && source.isLive(); 4926 if(isLive){ 4927 geomLock.getLock(); 4928 } 4929 dirtyFlag |= TEXTURE_CHANGED; 4930 4931 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4932 this.vertexData[j] = texCoords[i].x; 4933 this.vertexData[j+1] = texCoords[i].y; 4934 this.vertexData[j+2] = texCoords[i].z; 4935 } 4936 if(isLive) { 4937 geomLock.unLock(); 4938 sendDataChangedMessage(false); 4939 } 4940 4941 } 4942 4943 /** 4944 * Sets the texture coordinates associated with the vertices starting at 4945 * the specified index for this object using data in <code>texCoords</code> 4946 * starting at index <code>start</code> and ending at index <code>start+length</code>. 4947 * @param index the vertex index 4948 * @param texCoords the new texture coordinates 4949 * @param start starting texture coordinate index of data in <code>texCoords</code> . 4950 * @param length number of texture Coordinates to be copied. 4951 */ setTextureCoordinates(int texCoordSet, int index, TexCoord2f texCoords[], int start, int length)4952 void setTextureCoordinates(int texCoordSet, int index, TexCoord2f texCoords[], 4953 int start, int length) { 4954 boolean isLive = source!=null && source.isLive(); 4955 if(isLive){ 4956 geomLock.getLock(); 4957 } 4958 dirtyFlag |= TEXTURE_CHANGED; 4959 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) != 0) 4960 throw new IllegalStateException(J3dI18N.getString("GeometryArray82")); 4961 4962 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE ) == 0) 4963 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray79")); 4964 4965 int offset = this.stride*index + textureOffset + 4966 texCoordSet * texCoordStride; 4967 int i, j; 4968 4969 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 4970 this.vertexData[j] = texCoords[i].x; 4971 this.vertexData[j+1] = texCoords[i].y; 4972 } 4973 if(isLive) { 4974 geomLock.unLock(); 4975 sendDataChangedMessage(false); 4976 } 4977 4978 } 4979 4980 /** 4981 * Sets the texture coordinates associated with the vertices starting at 4982 * the specified index for this object using data in <code>texCoords</code> 4983 * starting at index <code>start</code> and ending at index <code>start+length</code>. 4984 * @param index the vertex index 4985 * @param texCoords the new texture coordinates 4986 * @param start starting texture coordinate index of data in <code>texCoords</code> . 4987 * @param length number of texture Coordinates to be copied. 4988 */ setTextureCoordinates(int texCoordSet, int index, TexCoord3f texCoords[], int start, int length)4989 void setTextureCoordinates(int texCoordSet, int index, 4990 TexCoord3f texCoords[], 4991 int start, int length) { 4992 boolean isLive = source!=null && source.isLive(); 4993 if(isLive){ 4994 geomLock.getLock(); 4995 } 4996 dirtyFlag |= TEXTURE_CHANGED; 4997 4998 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) != 0) 4999 throw new IllegalStateException(J3dI18N.getString("GeometryArray82")); 5000 5001 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE ) == 0) 5002 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray79")); 5003 5004 int offset = this.stride*index + textureOffset + 5005 texCoordSet * texCoordStride; 5006 int i, j; 5007 5008 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 5009 this.vertexData[j] = texCoords[i].x; 5010 this.vertexData[j+1] = texCoords[i].y; 5011 this.vertexData[j+2] = texCoords[i].z; 5012 } 5013 if(isLive) { 5014 geomLock.unLock(); 5015 sendDataChangedMessage(false); 5016 } 5017 } 5018 5019 /** 5020 * Sets the texture coordinates associated with the vertices starting at 5021 * the specified index for this object using data in <code>texCoords</code> 5022 * starting at index <code>start</code> and ending at index <code>start+length</code>. 5023 * @param index the vertex index 5024 * @param texCoords the new texture coordinates 5025 * @param start starting texture coordinate index of data in <code>texCoords</code> . 5026 * @param length number of texture Coordinates to be copied. 5027 */ setTextureCoordinates(int texCoordSet, int index, TexCoord4f texCoords[], int start, int length)5028 void setTextureCoordinates(int texCoordSet, int index, 5029 TexCoord4f texCoords[], 5030 int start, int length) { 5031 boolean isLive = source!=null && source.isLive(); 5032 if(isLive){ 5033 geomLock.getLock(); 5034 } 5035 dirtyFlag |= TEXTURE_CHANGED; 5036 5037 if ((this.vertexFormat & GeometryArray.BY_REFERENCE) != 0) 5038 throw new IllegalStateException(J3dI18N.getString("GeometryArray82")); 5039 5040 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE ) == 0) 5041 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray79")); 5042 5043 int offset = this.stride*index + textureOffset + 5044 texCoordSet * texCoordStride; 5045 int i, j; 5046 5047 for (i = start, j = offset; i < start+length; i++, j += this.stride) { 5048 this.vertexData[j] = texCoords[i].x; 5049 this.vertexData[j+1] = texCoords[i].y; 5050 this.vertexData[j+2] = texCoords[i].z; 5051 this.vertexData[j+3] = texCoords[i].w; 5052 } 5053 if(isLive) { 5054 geomLock.unLock(); 5055 sendDataChangedMessage(false); 5056 } 5057 } 5058 5059 5060 /** 5061 * Sets the vertex attribute associated with the vertex at the 5062 * specified index in the specified vertex attribute number for 5063 * this object. 5064 * 5065 * @param vertexAttrNum vertex attribute number in this geometry array 5066 * @param index destination vertex index in this geometry array 5067 * @param vertexAttr the Point2f containing the new vertex attribute 5068 */ setVertexAttr(int vertexAttrNum, int index, Point2f vertexAttr)5069 void setVertexAttr(int vertexAttrNum, int index, 5070 Point2f vertexAttr) { 5071 5072 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5073 boolean isLive = source!=null && source.isLive(); 5074 if(isLive){ 5075 geomLock.getLock(); 5076 } 5077 dirtyFlag |= VATTR_CHANGED; 5078 5079 this.vertexData[offset] = vertexAttr.x; 5080 this.vertexData[offset+1] = vertexAttr.y; 5081 5082 if(isLive) { 5083 geomLock.unLock(); 5084 sendDataChangedMessage(false); 5085 } 5086 } 5087 5088 /** 5089 * Sets the vertex attribute associated with the vertex at the 5090 * specified index in the specified vertex attribute number for 5091 * this object. 5092 * 5093 * @param vertexAttrNum vertex attribute number in this geometry array 5094 * @param index destination vertex index in this geometry array 5095 * @param vertexAttr the Point3f containing the new vertex attribute 5096 */ setVertexAttr(int vertexAttrNum, int index, Point3f vertexAttr)5097 void setVertexAttr(int vertexAttrNum, int index, 5098 Point3f vertexAttr) { 5099 5100 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5101 boolean isLive = source!=null && source.isLive(); 5102 if(isLive){ 5103 geomLock.getLock(); 5104 } 5105 dirtyFlag |= VATTR_CHANGED; 5106 5107 this.vertexData[offset] = vertexAttr.x; 5108 this.vertexData[offset+1] = vertexAttr.y; 5109 this.vertexData[offset+2] = vertexAttr.z; 5110 5111 if (isLive) { 5112 geomLock.unLock(); 5113 sendDataChangedMessage(false); 5114 } 5115 } 5116 5117 /** 5118 * Sets the vertex attribute associated with the vertex at the 5119 * specified index in the specified vertex attribute number for 5120 * this object. 5121 * 5122 * @param vertexAttrNum vertex attribute number in this geometry array 5123 * @param index destination vertex index in this geometry array 5124 * @param vertexAttr the Point4f containing the new vertex attribute 5125 */ setVertexAttr(int vertexAttrNum, int index, Point4f vertexAttr)5126 void setVertexAttr(int vertexAttrNum, int index, 5127 Point4f vertexAttr) { 5128 5129 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5130 boolean isLive = source!=null && source.isLive(); 5131 if(isLive){ 5132 geomLock.getLock(); 5133 } 5134 dirtyFlag |= VATTR_CHANGED; 5135 5136 this.vertexData[offset] = vertexAttr.x; 5137 this.vertexData[offset+1] = vertexAttr.y; 5138 this.vertexData[offset+2] = vertexAttr.z; 5139 this.vertexData[offset+3] = vertexAttr.w; 5140 5141 if(isLive) { 5142 geomLock.unLock(); 5143 sendDataChangedMessage(false); 5144 } 5145 } 5146 5147 /** 5148 * Sets the vertex attributes associated with the vertices 5149 * starting at the specified index in the specified vertex 5150 * attribute number for this object using data in 5151 * <code>vertexAttrs</code> starting at index <code>start</code> and 5152 * ending at index <code>start+length</code>. 5153 * 5154 * @param index starting destination vertex index in this geometry array 5155 * @param vertexAttrs source array of 1*n, 2*n, 3*n, or 4*n values 5156 * containing n new vertex attributes 5157 * @param start starting source vertex index in <code>vertexAttrs</code> 5158 * array. 5159 * @param length number of vertex attributes to be copied. 5160 */ setVertexAttrs(int vertexAttrNum, int index, float[] vertexAttrs, int start, int length)5161 void setVertexAttrs(int vertexAttrNum, int index, 5162 float[] vertexAttrs, 5163 int start, int length) { 5164 5165 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5166 int size = vertexAttrSizes[vertexAttrNum]; 5167 int i, j, k; 5168 boolean isLive = source!=null && source.isLive(); 5169 if(isLive){ 5170 geomLock.getLock(); 5171 } 5172 dirtyFlag |= VATTR_CHANGED; 5173 5174 for (i = start * size, j = offset, k = 0; k < length; i += size, j += this.stride, k++) { 5175 for (int ii = 0; ii < size; ii++) { 5176 this.vertexData[j+ii] = vertexAttrs[i+ii]; 5177 } 5178 } 5179 5180 if(isLive) { 5181 geomLock.unLock(); 5182 sendDataChangedMessage(false); 5183 } 5184 } 5185 5186 /** 5187 * Sets the vertex attributes associated with the vertices 5188 * starting at the specified index in the specified vertex 5189 * attribute number for this object using data in 5190 * <code>vertexAttrs</code> starting at index <code>start</code> and 5191 * ending at index <code>start+length</code>. 5192 * 5193 * @param vertexAttrNum vertex attribute number in this geometry array 5194 * @param index starting destination vertex index in this geometry array 5195 * @param vertexAttrs source array of Point2f objects containing new 5196 * vertex attributes 5197 * @param start starting source vertex index in <code>vertexAttrs</code> 5198 * array. 5199 * @param length number of vertex attributes to be copied. 5200 */ setVertexAttrs(int vertexAttrNum, int index, Point2f[] vertexAttrs, int start, int length)5201 void setVertexAttrs(int vertexAttrNum, int index, 5202 Point2f[] vertexAttrs, 5203 int start, int length) { 5204 5205 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5206 int i, j, k; 5207 boolean isLive = source!=null && source.isLive(); 5208 if(isLive){ 5209 geomLock.getLock(); 5210 } 5211 dirtyFlag |= VATTR_CHANGED; 5212 5213 for (i = start, j = offset, k = 0; k < length; i++, j += this.stride, k++) { 5214 this.vertexData[j] = vertexAttrs[i].x; 5215 this.vertexData[j+1] = vertexAttrs[i].y; 5216 } 5217 if(isLive) { 5218 geomLock.unLock(); 5219 sendDataChangedMessage(false); 5220 } 5221 } 5222 5223 /** 5224 * Sets the vertex attributes associated with the vertices 5225 * starting at the specified index in the specified vertex 5226 * attribute number for this object using data in 5227 * <code>vertexAttrs</code> starting at index <code>start</code> and 5228 * ending at index <code>start+length</code>. 5229 * 5230 * @param vertexAttrNum vertex attribute number in this geometry array 5231 * @param index starting destination vertex index in this geometry array 5232 * @param vertexAttrs source array of Point3f objects containing new 5233 * vertex attributes 5234 * @param start starting source vertex index in <code>vertexAttrs</code> 5235 * array. 5236 * @param length number of vertex attributes to be copied. 5237 */ setVertexAttrs(int vertexAttrNum, int index, Point3f[] vertexAttrs, int start, int length)5238 void setVertexAttrs(int vertexAttrNum, int index, 5239 Point3f[] vertexAttrs, 5240 int start, int length) { 5241 5242 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5243 int i, j, k; 5244 boolean isLive = source!=null && source.isLive(); 5245 if(isLive){ 5246 geomLock.getLock(); 5247 } 5248 dirtyFlag |= VATTR_CHANGED; 5249 5250 for (i = start, j = offset, k = 0; k < length; i++, j += this.stride, k++) { 5251 this.vertexData[j] = vertexAttrs[i].x; 5252 this.vertexData[j+1] = vertexAttrs[i].y; 5253 this.vertexData[j+2] = vertexAttrs[i].z; 5254 } 5255 if(isLive) { 5256 geomLock.unLock(); 5257 sendDataChangedMessage(false); 5258 } 5259 } 5260 5261 /** 5262 * Sets the vertex attributes associated with the vertices 5263 * starting at the specified index in the specified vertex 5264 * attribute number for this object using data in 5265 * <code>vertexAttrs</code> starting at index <code>start</code> and 5266 * ending at index <code>start+length</code>. 5267 * 5268 * @param vertexAttrNum vertex attribute number in this geometry array 5269 * @param index starting destination vertex index in this geometry array 5270 * @param vertexAttrs source array of Point4f objects containing new 5271 * vertex attributes 5272 * @param start starting source vertex index in <code>vertexAttrs</code> 5273 * array. 5274 * @param length number of vertex attributes to be copied. 5275 */ setVertexAttrs(int vertexAttrNum, int index, Point4f[] vertexAttrs, int start, int length)5276 void setVertexAttrs(int vertexAttrNum, int index, 5277 Point4f[] vertexAttrs, 5278 int start, int length) { 5279 5280 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5281 int i, j, k; 5282 5283 boolean isLive = source!=null && source.isLive(); 5284 if(isLive){ 5285 geomLock.getLock(); 5286 } 5287 dirtyFlag |= VATTR_CHANGED; 5288 5289 for (i = start, j = offset, k = 0; k < length; i++, j += this.stride, k++) { 5290 this.vertexData[j] = vertexAttrs[i].x; 5291 this.vertexData[j+1] = vertexAttrs[i].y; 5292 this.vertexData[j+2] = vertexAttrs[i].z; 5293 this.vertexData[j+3] = vertexAttrs[i].w; 5294 } 5295 if(isLive) { 5296 geomLock.unLock(); 5297 sendDataChangedMessage(false); 5298 } 5299 } 5300 5301 5302 /** 5303 * Gets the coordinate associated with the vertex at 5304 * the specified index. 5305 * @param index the vertex index 5306 * @param coordinate an array of 3 values that will receive the new coordinate 5307 */ getCoordinate(int index, float coordinate[])5308 void getCoordinate(int index, float coordinate[]) { 5309 int offset = this.stride*index + coordinateOffset; 5310 5311 coordinate[0]= this.vertexData[offset]; 5312 coordinate[1]= this.vertexData[offset+1]; 5313 coordinate[2]= this.vertexData[offset+2]; 5314 } 5315 5316 /** 5317 * Gets the coordinate associated with the vertex at 5318 * the specified index. 5319 * @param index the vertex index 5320 * @param coordinate an array of 3 values that will receive the new coordinate 5321 */ getCoordinate(int index, double coordinate[])5322 void getCoordinate(int index, double coordinate[]) { 5323 int offset = this.stride*index + coordinateOffset; 5324 5325 coordinate[0]= (double)this.vertexData[offset]; 5326 coordinate[1]= (double)this.vertexData[offset+1]; 5327 coordinate[2]= (double)this.vertexData[offset+2]; 5328 } 5329 5330 /** 5331 * Gets the coordinate associated with the vertex at 5332 * the specified index. 5333 * @param index the vertex index 5334 * @param coordinate a vector that will receive the new coordinate 5335 */ getCoordinate(int index, Point3f coordinate)5336 void getCoordinate(int index, Point3f coordinate) { 5337 int offset = this.stride*index + coordinateOffset; 5338 5339 coordinate.x = this.vertexData[offset]; 5340 coordinate.y = this.vertexData[offset+1]; 5341 coordinate.z = this.vertexData[offset+2]; 5342 } 5343 5344 /** 5345 * Gets the coordinate associated with the vertex at 5346 * the specified index. 5347 * @param index the vertex index 5348 * @param coordinate a vector that will receive the new coordinate 5349 */ getCoordinate(int index, Point3d coordinate)5350 void getCoordinate(int index, Point3d coordinate) { 5351 int offset = this.stride*index + coordinateOffset; 5352 5353 coordinate.x = (double)this.vertexData[offset]; 5354 coordinate.y = (double)this.vertexData[offset+1]; 5355 coordinate.z = (double)this.vertexData[offset+2]; 5356 } 5357 5358 /** 5359 * Gets the coordinates associated with the vertices starting at 5360 * the specified index. 5361 * @param index the vertex index 5362 * @param coordinates an array of 3*n values that will receive new coordinates 5363 */ getCoordinates(int index, float coordinates[])5364 void getCoordinates(int index, float coordinates[]) { 5365 int offset = this.stride*index + coordinateOffset; 5366 int i, j, num = coordinates.length; 5367 5368 for (i=0,j= offset;i < num;i +=3, j += this.stride) 5369 { 5370 coordinates[i] = this.vertexData[j]; 5371 coordinates[i+1]= this.vertexData[j+1]; 5372 coordinates[i+2]= this.vertexData[j+2]; 5373 } 5374 } 5375 5376 5377 /** 5378 * Gets the coordinates associated with the vertices starting at 5379 * the specified index. 5380 * @param index the vertex index 5381 * @param coordinates an array of 3*n values that will receive new coordinates 5382 */ getCoordinates(int index, double coordinates[])5383 void getCoordinates(int index, double coordinates[]) { 5384 int offset = this.stride*index + coordinateOffset; 5385 int i, j, num = coordinates.length; 5386 5387 for (i=0,j= offset;i < num;i +=3, j += this.stride) 5388 { 5389 coordinates[i] = (double)this.vertexData[j]; 5390 coordinates[i+1]= (double)this.vertexData[j+1]; 5391 coordinates[i+2]= (double)this.vertexData[j+2]; 5392 } 5393 } 5394 5395 /** 5396 * Gets the coordinates associated with the vertices starting at 5397 * the specified index. 5398 * @param index the vertex index 5399 * @param coordinates an array of vectors that will receive new coordinates 5400 */ getCoordinates(int index, Point3f coordinates[])5401 void getCoordinates(int index, Point3f coordinates[]) { 5402 int offset = this.stride*index + coordinateOffset; 5403 int i, j, num = coordinates.length; 5404 5405 for (i=0,j= offset;i < num;i++, j += this.stride) 5406 { 5407 coordinates[i].x = this.vertexData[j]; 5408 coordinates[i].y = this.vertexData[j+1]; 5409 coordinates[i].z = this.vertexData[j+2]; 5410 } 5411 } 5412 5413 /** 5414 * Gets the coordinates associated with the vertices starting at 5415 * the specified index. 5416 * @param index the vertex index 5417 * @param coordinates an array of vectors that will receive new coordinates 5418 */ getCoordinates(int index, Point3d coordinates[])5419 void getCoordinates(int index, Point3d coordinates[]) { 5420 int offset = this.stride*index + coordinateOffset; 5421 int i, j, num = coordinates.length; 5422 5423 for (i=0,j= offset;i < num;i++, j += this.stride) 5424 { 5425 coordinates[i].x = (double)this.vertexData[j]; 5426 coordinates[i].y = (double)this.vertexData[j+1]; 5427 coordinates[i].z = (double)this.vertexData[j+2]; 5428 } 5429 } 5430 5431 /** 5432 * Gets the color associated with the vertex at 5433 * the specified index. 5434 * @param index the vertex index 5435 * @param color an array of 3 or 4 values that will receive the new color 5436 */ getColor(int index, float color[])5437 void getColor(int index, float color[]) { 5438 int offset = this.stride*index + colorOffset; 5439 5440 color[0]= this.vertexData[offset]; 5441 color[1]= this.vertexData[offset+1]; 5442 color[2]= this.vertexData[offset+2]; 5443 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 5444 color[3]= this.vertexData[offset+3]/lastAlpha[0]; 5445 } 5446 5447 /** 5448 * Gets the color associated with the vertex at 5449 * the specified index. 5450 * @param index the vertex index 5451 * @param color an array of 3 or 4 values that will receive the new color 5452 */ getColor(int index, byte color[])5453 void getColor(int index, byte color[]) { 5454 int offset = this.stride*index + colorOffset; 5455 5456 color[0]= (byte)(this.vertexData[offset] * FloatToByteScale); 5457 color[1]= (byte)(this.vertexData[offset+1] * FloatToByteScale); 5458 color[2]= (byte)(this.vertexData[offset+2] * FloatToByteScale); 5459 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 5460 color[3]= (byte)((this.vertexData[offset+3]/lastAlpha[0]) * FloatToByteScale); 5461 } 5462 5463 /** 5464 * Gets the color associated with the vertex at 5465 * the specified index. 5466 * @param index the vertex index 5467 * @param color a vector that will receive the new color 5468 */ getColor(int index, Color3f color)5469 void getColor(int index, Color3f color) { 5470 int offset = this.stride*index + colorOffset; 5471 5472 color.x = this.vertexData[offset]; 5473 color.y = this.vertexData[offset+1]; 5474 color.z = this.vertexData[offset+2]; 5475 } 5476 5477 /** 5478 * Gets the color associated with the vertex at 5479 * the specified index. 5480 * @param index the vertex index 5481 * @param color a vector that will receive the new color 5482 */ getColor(int index, Color4f color)5483 void getColor(int index, Color4f color) { 5484 int offset = this.stride*index + colorOffset; 5485 5486 color.x = this.vertexData[offset]; 5487 color.y = this.vertexData[offset+1]; 5488 color.z = this.vertexData[offset+2]; 5489 color.w= this.vertexData[offset+3]/lastAlpha[0]; 5490 } 5491 5492 /** 5493 * Gets the color associated with the vertex at 5494 * the specified index. 5495 * @param index the vertex index 5496 * @param color a vector that will receive the new color 5497 */ getColor(int index, Color3b color)5498 void getColor(int index, Color3b color) { 5499 int offset = this.stride*index + colorOffset; 5500 5501 color.x = (byte)(this.vertexData[offset] * FloatToByteScale); 5502 color.y = (byte)(this.vertexData[offset+1] * FloatToByteScale); 5503 color.z = (byte)(this.vertexData[offset+2] * FloatToByteScale); 5504 } 5505 5506 /** 5507 * Gets the color associated with the vertex at 5508 * the specified index. 5509 * @param index the vertex index 5510 * @param color a vector that will receive the new color 5511 */ getColor(int index, Color4b color)5512 void getColor(int index, Color4b color) { 5513 int offset = this.stride*index + colorOffset; 5514 5515 color.x = (byte)(this.vertexData[offset] * FloatToByteScale); 5516 color.y = (byte)(this.vertexData[offset+1] * FloatToByteScale); 5517 color.z = (byte)(this.vertexData[offset+2] * FloatToByteScale); 5518 color.w = (byte)((this.vertexData[offset+3]/lastAlpha[0]) * FloatToByteScale); 5519 } 5520 5521 /** 5522 * Gets the colors associated with the vertices starting at 5523 * the specified index. 5524 * @param index the vertex index 5525 * @param colors an array of 3*n or 4*n values that will receive n new colors 5526 */ getColors(int index, float colors[])5527 void getColors(int index, float colors[]) { 5528 int offset = this.stride*index + colorOffset; 5529 int i, j, num = colors.length; 5530 float val = 1.0f/lastAlpha[0]; 5531 5532 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 5533 { 5534 for (i=0, j= offset;i < num; i+= 4, j+= this.stride) 5535 { 5536 colors[i] = this.vertexData[j]; 5537 colors[i+1]= this.vertexData[j+1]; 5538 colors[i+2]= this.vertexData[j+2]; 5539 colors[i+3]= this.vertexData[j+3] * val; 5540 } 5541 } 5542 else 5543 { 5544 for (i=0, j= offset;i < num; i+= 3, j+= this.stride) 5545 { 5546 colors[i] = this.vertexData[j]; 5547 colors[i+1]= this.vertexData[j+1]; 5548 colors[i+2]= this.vertexData[j+2]; 5549 } 5550 } 5551 } 5552 5553 /** 5554 * Gets the colors associated with the vertices starting at 5555 * the specified index. 5556 * @param index the vertex index 5557 * @param colors an array of 3*n or 4*n values that will receive new colors 5558 */ getColors(int index, byte colors[])5559 void getColors(int index, byte colors[]) { 5560 int offset = this.stride*index + colorOffset; 5561 int i, j, num = colors.length; 5562 float val = 1.0f/lastAlpha[0]; 5563 5564 5565 if ((this.vertexFormat & GeometryArray.WITH_ALPHA) != 0) 5566 { 5567 for (i=0, j= offset;i < num; i+= 4, j+= this.stride) 5568 { 5569 colors[i] = (byte)(this.vertexData[j] * FloatToByteScale); 5570 colors[i+1]= (byte)(this.vertexData[j+1] * FloatToByteScale); 5571 colors[i+2]= (byte)(this.vertexData[j+2] * FloatToByteScale); 5572 colors[i+3]= (byte)((this.vertexData[j+3] * val) * FloatToByteScale); 5573 } 5574 } 5575 else 5576 { 5577 for (i=0, j= offset;i < num; i+= 3, j+= this.stride) 5578 { 5579 colors[i] = (byte)(this.vertexData[j] * FloatToByteScale); 5580 colors[i+1]= (byte)(this.vertexData[j+1] * FloatToByteScale); 5581 colors[i+2]= (byte)(this.vertexData[j+2] * FloatToByteScale); 5582 } 5583 } 5584 } 5585 5586 /** 5587 * Gets the colors associated with the vertices starting at 5588 * the specified index. 5589 * @param index the vertex index 5590 * @param colors an array of vectors that will receive new colors 5591 */ getColors(int index, Color3f colors[])5592 void getColors(int index, Color3f colors[]) { 5593 int offset = this.stride*index + colorOffset; 5594 int i, j, num = colors.length; 5595 5596 for (i=0, j= offset;i < num; i++, j+= this.stride) 5597 { 5598 colors[i].x = this.vertexData[j]; 5599 colors[i].y = this.vertexData[j+1]; 5600 colors[i].z = this.vertexData[j+2]; 5601 } 5602 } 5603 5604 /** 5605 * Gets the colors associated with the vertices starting at 5606 * the specified index. 5607 * @param index the vertex index 5608 * @param colors an array of vectors that will receive new colors 5609 */ getColors(int index, Color4f colors[])5610 void getColors(int index, Color4f colors[]) { 5611 int offset = this.stride*index + colorOffset; 5612 int i, j, num = colors.length; 5613 float val = 1.0f/lastAlpha[0]; 5614 5615 for (i=0, j= offset;i < num; i++, j+= this.stride) 5616 { 5617 colors[i].x = this.vertexData[j]; 5618 colors[i].y = this.vertexData[j+1]; 5619 colors[i].z = this.vertexData[j+2]; 5620 colors[i].w = this.vertexData[j+3] * val; 5621 } 5622 } 5623 5624 /** 5625 * Gets the colors associated with the vertices starting at 5626 * the specified index. 5627 * @param index the vertex index 5628 * @param colors an array of vectors that will receive new colors 5629 */ getColors(int index, Color3b colors[])5630 void getColors(int index, Color3b colors[]) { 5631 int offset = this.stride*index + colorOffset; 5632 int i, j, num = colors.length; 5633 5634 for (i=0, j= offset;i < num; i++, j+= this.stride) 5635 { 5636 colors[i].x = (byte)(this.vertexData[j] * FloatToByteScale); 5637 colors[i].y = (byte)(this.vertexData[j+1] * FloatToByteScale); 5638 colors[i].z = (byte)(this.vertexData[j+2] * FloatToByteScale); 5639 } 5640 } 5641 5642 /** 5643 * Gets the colors associated with the vertices starting at 5644 * the specified index. 5645 * @param index the vertex index 5646 * @param colors an array of vectors that will receive new colors 5647 */ getColors(int index, Color4b colors[])5648 void getColors(int index, Color4b colors[]) { 5649 int offset = this.stride*index + colorOffset; 5650 int i, j, num = colors.length; 5651 float val = 1.0f/lastAlpha[0]; 5652 5653 for (i=0, j= offset;i < num; i++, j+= this.stride) 5654 { 5655 colors[i].x = (byte)(this.vertexData[j] * FloatToByteScale); 5656 colors[i].y = (byte)(this.vertexData[j+1] * FloatToByteScale); 5657 colors[i].z = (byte)(this.vertexData[j+2] * FloatToByteScale); 5658 colors[i].w = (byte)(this.vertexData[j+3] * val * FloatToByteScale); 5659 } 5660 } 5661 5662 /** 5663 * Gets the normal associated with the vertex at 5664 * the specified index. 5665 * @param index the vertex index 5666 * @param normal array that will receive the new normal 5667 */ getNormal(int index, float normal[])5668 void getNormal(int index, float normal[]) { 5669 int offset = this.stride*index + normalOffset; 5670 5671 normal[0]= this.vertexData[offset]; 5672 normal[1]= this.vertexData[offset+1]; 5673 normal[2]= this.vertexData[offset+2]; 5674 } 5675 5676 /** 5677 * Gets the normal associated with the vertex at 5678 * the specified index. 5679 * @param index the vertex index 5680 * @param normal the vector that will receive the new normal 5681 */ getNormal(int index, Vector3f normal)5682 void getNormal(int index, Vector3f normal) { 5683 int offset = this.stride*index + normalOffset; 5684 5685 normal.x= this.vertexData[offset]; 5686 normal.y= this.vertexData[offset+1]; 5687 normal.z= this.vertexData[offset+2]; 5688 } 5689 5690 /** 5691 * Gets the normals associated with the vertices starting at 5692 * the specified index. 5693 * @param index the vertex index 5694 * @param normals array that will receive the new normals 5695 */ getNormals(int index, float normals[])5696 void getNormals(int index, float normals[]) { 5697 int offset = this.stride*index + normalOffset; 5698 int i, j, num = normals.length; 5699 5700 for (i=0, j= offset;i < num;i+=3, j+= this.stride) 5701 { 5702 normals[i] = this.vertexData[j]; 5703 normals[i+1]= this.vertexData[j+1]; 5704 normals[i+2]= this.vertexData[j+2]; 5705 } 5706 } 5707 5708 /** 5709 * Gets the normals associated with the vertices starting at 5710 * the specified index. 5711 * @param index the vertex index 5712 * @param normals the vector that will receive the new normals 5713 */ getNormals(int index, Vector3f normals[])5714 void getNormals(int index, Vector3f normals[]) { 5715 int offset = this.stride*index + normalOffset; 5716 int i, j, num = normals.length; 5717 5718 for (i=0, j= offset;i < num;i++, j+= this.stride) 5719 { 5720 normals[i].x= this.vertexData[j]; 5721 normals[i].y= this.vertexData[j+1]; 5722 normals[i].z= this.vertexData[j+2]; 5723 } 5724 } 5725 5726 /** 5727 * Gets the texture co-ordinate associated with the vertex at 5728 * the specified index. 5729 * @param index the vertex index 5730 * @param texCoord array that will receive the new texture co-ordinate 5731 */ getTextureCoordinate(int texCoordSet, int index, float texCoord[])5732 void getTextureCoordinate(int texCoordSet, int index, float texCoord[]) { 5733 int offset = this.stride*index + textureOffset + 5734 texCoordSet * texCoordStride; 5735 5736 texCoord[0]= this.vertexData[offset]; 5737 texCoord[1]= this.vertexData[offset+1]; 5738 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 5739 texCoord[2]= this.vertexData[offset+2]; 5740 5741 } else if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) 5742 != 0) { 5743 texCoord[2]= this.vertexData[offset+2]; 5744 texCoord[3]= this.vertexData[offset+3]; 5745 } 5746 } 5747 5748 /** 5749 * Gets the texture co-ordinate associated with the vertex at 5750 * the specified index. 5751 * @param index the vertex index 5752 * @param texCoord the vector that will receive the new texture co-ordinates 5753 */ getTextureCoordinate(int texCoordSet, int index, TexCoord2f texCoord)5754 void getTextureCoordinate(int texCoordSet, int index, TexCoord2f texCoord) { 5755 int offset = this.stride*index + textureOffset + 5756 texCoordSet * texCoordStride; 5757 5758 texCoord.x= this.vertexData[offset]; 5759 texCoord.y= this.vertexData[offset+1]; 5760 } 5761 5762 /** 5763 * Gets the texture co-ordinate associated with the vertex at 5764 * the specified index. 5765 * @param index the vertex index 5766 * @param texCoord the vector that will receive the new texture co-ordinates 5767 */ getTextureCoordinate(int texCoordSet, int index, TexCoord3f texCoord)5768 void getTextureCoordinate(int texCoordSet, int index, TexCoord3f texCoord) { 5769 int offset = this.stride*index + textureOffset + 5770 texCoordSet * texCoordStride; 5771 5772 texCoord.x= this.vertexData[offset]; 5773 texCoord.y= this.vertexData[offset+1]; 5774 texCoord.z= this.vertexData[offset+2]; 5775 } 5776 5777 /** 5778 * Gets the texture co-ordinate associated with the vertex at 5779 * the specified index. 5780 * @param index the vertex index 5781 * @param texCoord the vector that will receive the new texture co-ordinates 5782 */ getTextureCoordinate(int texCoordSet, int index, TexCoord4f texCoord)5783 void getTextureCoordinate(int texCoordSet, int index, TexCoord4f texCoord) { 5784 int offset = this.stride*index + textureOffset + 5785 texCoordSet * texCoordStride; 5786 5787 texCoord.x= this.vertexData[offset]; 5788 texCoord.y= this.vertexData[offset+1]; 5789 texCoord.z= this.vertexData[offset+2]; 5790 texCoord.w= this.vertexData[offset+3]; 5791 } 5792 5793 /** 5794 * Gets the texture co-ordinates associated with the vertices starting at 5795 * the specified index. 5796 * @param index the vertex index 5797 * @param texCoords array that will receive the new texture co-ordinates 5798 */ getTextureCoordinates(int texCoordSet, int index, float texCoords[])5799 void getTextureCoordinates(int texCoordSet, int index, float texCoords[]) { 5800 int offset = this.stride*index + textureOffset + 5801 texCoordSet * texCoordStride; 5802 int i, j, num = texCoords.length; 5803 5804 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 5805 for (i=0, j= offset;i < num;i+=4, j+= this.stride) 5806 { 5807 texCoords[i]= this.vertexData[j]; 5808 texCoords[i+1]= this.vertexData[j+1]; 5809 texCoords[i+2]= this.vertexData[j+2]; 5810 texCoords[i+3]= this.vertexData[j+3]; 5811 } 5812 } else if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) 5813 != 0) { 5814 for (i=0, j= offset;i < num;i+=3, j+= this.stride) 5815 { 5816 texCoords[i]= this.vertexData[j]; 5817 texCoords[i+1]= this.vertexData[j+1]; 5818 texCoords[i+2]= this.vertexData[j+2]; 5819 } 5820 } else { 5821 for (i=0, j= offset;i < num;i+=2, j+= this.stride) 5822 { 5823 texCoords[i]= this.vertexData[j]; 5824 texCoords[i+1]= this.vertexData[j+1]; 5825 } 5826 } 5827 } 5828 5829 /** 5830 * Gets the texture co-ordinates associated with the vertices starting at 5831 * the specified index. 5832 * @param index the vertex index 5833 * @param texCoords the vector that will receive the new texture co-ordinates 5834 */ getTextureCoordinates(int texCoordSet, int index, TexCoord2f texCoords[])5835 void getTextureCoordinates(int texCoordSet, int index, 5836 TexCoord2f texCoords[]) { 5837 int offset = this.stride*index + textureOffset + 5838 texCoordSet * texCoordStride; 5839 int i, j, num = texCoords.length; 5840 5841 for (i=0, j= offset;i < num;i++, j+= this.stride) 5842 { 5843 texCoords[i].x= this.vertexData[j]; 5844 texCoords[i].y= this.vertexData[j+1]; 5845 } 5846 } 5847 5848 /** 5849 * Gets the texture co-ordinates associated with the vertices starting at 5850 * the specified index. 5851 * @param index the vertex index 5852 * @param texCoords the vector that will receive the new texture co-ordinates 5853 */ getTextureCoordinates(int texCoordSet, int index, TexCoord3f texCoords[])5854 void getTextureCoordinates(int texCoordSet, int index, TexCoord3f texCoords[]) { 5855 int offset = this.stride*index + textureOffset + 5856 texCoordSet * texCoordStride; 5857 int i, j, num = texCoords.length; 5858 5859 for (i=0, j= offset;i < num;i++, j+= this.stride) 5860 { 5861 texCoords[i].x= this.vertexData[j]; 5862 texCoords[i].y= this.vertexData[j+1]; 5863 texCoords[i].z= this.vertexData[j+2]; 5864 } 5865 } 5866 5867 /** 5868 * Gets the texture co-ordinates associated with the vertices starting at 5869 * the specified index. 5870 * @param index the vertex index 5871 * @param texCoords the vector that will receive the new texture co-ordinates 5872 */ getTextureCoordinates(int texCoordSet, int index, TexCoord4f texCoords[])5873 void getTextureCoordinates(int texCoordSet, int index, TexCoord4f texCoords[]) { 5874 int offset = this.stride*index + textureOffset + 5875 texCoordSet * texCoordStride; 5876 int i, j, num = texCoords.length; 5877 5878 for (i=0, j= offset;i < num;i++, j+= this.stride) 5879 { 5880 texCoords[i].x= this.vertexData[j]; 5881 texCoords[i].y= this.vertexData[j+1]; 5882 texCoords[i].z= this.vertexData[j+2]; 5883 texCoords[i].w= this.vertexData[j+3]; 5884 } 5885 } 5886 getTextureCoordinates(int texCoordSet, int index, Point2f texCoords[])5887 void getTextureCoordinates(int texCoordSet, int index, 5888 Point2f texCoords[]) { 5889 int offset = this.stride*index + textureOffset + 5890 texCoordSet * texCoordStride; 5891 int i, j, num = texCoords.length; 5892 5893 for (i=0, j= offset;i < num;i++, j+= this.stride) 5894 { 5895 texCoords[i].x= this.vertexData[j]; 5896 texCoords[i].y= this.vertexData[j+1]; 5897 } 5898 } 5899 getTextureCoordinates(int texCoordSet, int index, Point3f texCoords[])5900 void getTextureCoordinates(int texCoordSet, int index, Point3f texCoords[]) { 5901 int offset = this.stride*index + textureOffset + 5902 texCoordSet * texCoordStride; 5903 int i, j, num = texCoords.length; 5904 5905 for (i=0, j= offset;i < num;i++, j+= this.stride) 5906 { 5907 texCoords[i].x= this.vertexData[j]; 5908 texCoords[i].y= this.vertexData[j+1]; 5909 texCoords[i].z= this.vertexData[j+2]; 5910 } 5911 } 5912 5913 5914 /** 5915 * Gets the vertex attribute associated with the vertex at 5916 * the specified index in the specified vertex attribute number 5917 * for this object. 5918 */ getVertexAttr(int vertexAttrNum, int index, float[] vertexAttr)5919 public void getVertexAttr(int vertexAttrNum, int index, 5920 float[] vertexAttr) { 5921 5922 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5923 int size = vertexAttrSizes[vertexAttrNum]; 5924 5925 for (int i = 0; i < size; i++) { 5926 vertexAttr[i] = this.vertexData[offset+i]; 5927 5928 } 5929 5930 } 5931 5932 /** 5933 * Gets the vertex attribute associated with the vertex at 5934 * the specified index in the specified vertex attribute number 5935 * for this object. 5936 */ getVertexAttr(int vertexAttrNum, int index, Point2f vertexAttr)5937 public void getVertexAttr(int vertexAttrNum, int index, 5938 Point2f vertexAttr) { 5939 5940 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5941 5942 vertexAttr.x = this.vertexData[offset]; 5943 vertexAttr.y = this.vertexData[offset+1]; 5944 5945 } 5946 5947 /** 5948 * Gets the vertex attribute associated with the vertex at 5949 * the specified index in the specified vertex attribute number 5950 * for this object. 5951 */ getVertexAttr(int vertexAttrNum, int index, Point3f vertexAttr)5952 public void getVertexAttr(int vertexAttrNum, int index, 5953 Point3f vertexAttr) { 5954 5955 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5956 5957 vertexAttr.x = this.vertexData[offset]; 5958 vertexAttr.y = this.vertexData[offset+1]; 5959 vertexAttr.z = this.vertexData[offset+2]; 5960 5961 } 5962 5963 /** 5964 * Gets the vertex attribute associated with the vertex at 5965 * the specified index in the specified vertex attribute number 5966 * for this object. 5967 */ getVertexAttr(int vertexAttrNum, int index, Point4f vertexAttr)5968 public void getVertexAttr(int vertexAttrNum, int index, 5969 Point4f vertexAttr) { 5970 5971 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5972 5973 vertexAttr.x = this.vertexData[offset]; 5974 vertexAttr.y = this.vertexData[offset+1]; 5975 vertexAttr.z = this.vertexData[offset+2]; 5976 vertexAttr.w = this.vertexData[offset+3]; 5977 5978 } 5979 5980 /** 5981 * Gets the vertex attributes associated with the vertices starting at 5982 * the specified index in the specified vertex attribute number 5983 * for this object. 5984 */ getVertexAttrs(int vertexAttrNum, int index, float[] vertexAttrs)5985 public void getVertexAttrs(int vertexAttrNum, int index, 5986 float[] vertexAttrs) { 5987 5988 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 5989 int size = vertexAttrSizes[vertexAttrNum]; 5990 int i, j, k; 5991 5992 for (i = 0, j = offset; 5993 ((i < vertexAttrs.length) && (j < this.vertexData.length)) ; 5994 i += size, j += this.stride) { 5995 for (k = 0; k < size; k++) { 5996 vertexAttrs[i+k] = this.vertexData[j+k]; 5997 } 5998 } 5999 6000 } 6001 6002 /** 6003 * Gets the vertex attributes associated with the vertices starting at 6004 * the specified index in the specified vertex attribute number 6005 * for this object. 6006 */ getVertexAttrs(int vertexAttrNum, int index, Point2f[] vertexAttrs)6007 public void getVertexAttrs(int vertexAttrNum, int index, 6008 Point2f[] vertexAttrs) { 6009 6010 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 6011 int i, j; 6012 6013 for (i = 0, j = offset; 6014 ((i < vertexAttrs.length) && (j < this.vertexData.length)) ; 6015 i++, j += this.stride) { 6016 vertexAttrs[i].x = this.vertexData[j]; 6017 vertexAttrs[i].y = this.vertexData[j+1]; 6018 } 6019 6020 } 6021 6022 /** 6023 * Gets the vertex attributes associated with the vertices starting at 6024 * the specified index in the specified vertex attribute number 6025 * for this object. 6026 */ getVertexAttrs(int vertexAttrNum, int index, Point3f[] vertexAttrs)6027 public void getVertexAttrs(int vertexAttrNum, int index, 6028 Point3f[] vertexAttrs) { 6029 6030 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 6031 int i, j; 6032 6033 for (i = 0, j = offset; 6034 ((i < vertexAttrs.length) && (j < this.vertexData.length)) ; 6035 i++, j += this.stride) { 6036 vertexAttrs[i].x = this.vertexData[j]; 6037 vertexAttrs[i].y = this.vertexData[j+1]; 6038 vertexAttrs[i].z = this.vertexData[j+2]; 6039 } 6040 6041 } 6042 6043 /** 6044 * Gets the vertex attributes associated with the vertices starting at 6045 * the specified index in the specified vertex attribute number 6046 * for this object. 6047 */ getVertexAttrs(int vertexAttrNum, int index, Point4f[] vertexAttrs)6048 public void getVertexAttrs(int vertexAttrNum, int index, 6049 Point4f[] vertexAttrs) { 6050 6051 int offset = this.stride*index + vertexAttrOffsets[vertexAttrNum]; 6052 int i, j; 6053 6054 for (i = 0, j = offset; 6055 ((i < vertexAttrs.length) && (j < this.vertexData.length)) ; 6056 i++, j += this.stride) { 6057 vertexAttrs[i].x = this.vertexData[j]; 6058 vertexAttrs[i].y = this.vertexData[j+1]; 6059 vertexAttrs[i].z = this.vertexData[j+2]; 6060 vertexAttrs[i].w = this.vertexData[j+3]; 6061 } 6062 6063 } 6064 6065 6066 /** 6067 * Updates geometry array data. 6068 */ updateData(GeometryUpdater updater)6069 void updateData(GeometryUpdater updater) { 6070 boolean nullGeo = false; 6071 6072 // Add yourself to obtain the geometry lock 6073 // and Thread.currentThread().sleep until you get the lock 6074 geomLock.getLock(); 6075 6076 inUpdater = true; 6077 updater.updateData((Geometry)source); 6078 inUpdater = false; 6079 if ((vertexFormat & GeometryArray.BY_REFERENCE) != 0) { 6080 if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { 6081 // XXXX: handle the nio buffer 6082 if (!(this instanceof IndexedGeometryArrayRetained) || 6083 (vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) { 6084 if (((vertexFormat & GeometryArray.INTERLEAVED) != 0)) { 6085 setupMirrorInterleavedColorPointer(false); 6086 nullGeo = (interleavedFloatBufferImpl == null); 6087 } 6088 else { 6089 setupMirrorColorPointer((vertexType & COLOR_DEFINED), false); 6090 nullGeo = ((vertexType & GeometryArrayRetained.VERTEX_DEFINED) == 0); 6091 } 6092 } 6093 } 6094 else { 6095 if (!(this instanceof IndexedGeometryArrayRetained) || 6096 (vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) { 6097 if (((vertexFormat & GeometryArray.INTERLEAVED) != 0)) { 6098 setupMirrorInterleavedColorPointer(false); 6099 nullGeo = (interLeavedVertexData == null); 6100 } 6101 else { 6102 setupMirrorVertexPointer(vertexType & VERTEX_DEFINED); 6103 setupMirrorColorPointer((vertexType & COLOR_DEFINED), false); 6104 setupMirrorNormalPointer(vertexType & NORMAL_DEFINED); 6105 setupMirrorTexCoordPointer(texCoordType); 6106 setupMirrorVertexAttrPointer(vertexAttrType); 6107 nullGeo = ((vertexType & GeometryArrayRetained.VERTEX_DEFINED) == 0); 6108 } 6109 } 6110 } 6111 6112 //NVaidya 6113 // User may or may not have changed indices in updater callback. 6114 // We need to presume that the user may indeed have and, thus, will 6115 // need to recompute maxCoordIndex unconditionally while 6116 // geomLock is still locked. 6117 if ((vertexFormat & GeometryArray.BY_REFERENCE_INDICES) != 0) { 6118 assert (this instanceof IndexedGeometryArrayRetained); 6119 6120 if (((IndexedGeometryArrayRetained)this).getCoordIndicesRef() == null) { 6121 nullGeo = true; 6122 } 6123 ((IndexedGeometryArrayRetained)this).doPostUpdaterUpdate(); 6124 } 6125 } 6126 6127 dirtyFlag |= VERTEX_CHANGED; 6128 colorChanged = 0xffff; 6129 geomLock.unLock(); 6130 6131 if (source != null && source.isLive()) { 6132 processCoordsChanged(nullGeo); 6133 sendDataChangedMessage(true); 6134 } 6135 } 6136 intersectBoundingBox( Point3d coordinates[], BoundingBox box, double dist[], Point3d iPnt)6137 boolean intersectBoundingBox( Point3d coordinates[], 6138 BoundingBox box, 6139 double dist[], 6140 Point3d iPnt) { 6141 int i, j; 6142 int out[] = new int[6]; 6143 6144 //Do trivial vertex test. 6145 for(i=0; i<6; i++) 6146 out[i] = 0; 6147 for(i=0; i<coordinates.length; i++) { 6148 if((coordinates[i].x >= box.lower.x) && (coordinates[i].x <= box.upper.x) && 6149 (coordinates[i].y >= box.lower.y) && (coordinates[i].y <= box.upper.y) && 6150 (coordinates[i].z >= box.lower.z) && (coordinates[i].z <= box.upper.z)) 6151 // We're done! It's inside the boundingbox. 6152 return true; 6153 else { 6154 if(coordinates[i].x < box.lower.x) 6155 out[0]++; // left 6156 if(coordinates[i].y < box.lower.y) 6157 out[1]++; // bottom 6158 if(coordinates[i].z < box.lower.z) 6159 out[2]++; // back 6160 if(coordinates[i].x > box.upper.x) 6161 out[3]++; // right 6162 if(coordinates[i].y > box.upper.y) 6163 out[4]++; // top 6164 if(coordinates[i].z > box.upper.z) 6165 out[5]++; // front 6166 } 6167 6168 } 6169 6170 if((out[0] == coordinates.length) || (out[1] == coordinates.length) || 6171 (out[2] == coordinates.length) || (out[3] == coordinates.length) || 6172 (out[4] == coordinates.length) || (out[5] == coordinates.length)) 6173 // we're done. primitive is outside of boundingbox. 6174 return false; 6175 6176 // Setup bounding planes. 6177 Point3d pCoor[] = new Point3d[4]; 6178 for(i=0; i<4; i++) 6179 pCoor[i] = new Point3d(); 6180 6181 // left plane. 6182 pCoor[0].set(box.lower.x, box.lower.y, box.lower.z); 6183 pCoor[1].set(box.lower.x, box.lower.y, box.upper.z); 6184 pCoor[2].set(box.lower.x, box.upper.y, box.upper.z); 6185 pCoor[3].set(box.lower.x, box.upper.y, box.lower.z); 6186 6187 6188 if (intersectPolygon(pCoor, coordinates)) { 6189 if (dist != null) { 6190 computeMinDistance(pCoor, box.getCenter(), 6191 null, 6192 dist, iPnt); 6193 } 6194 return true; 6195 } 6196 6197 // right plane. 6198 pCoor[0].set(box.upper.x, box.lower.y, box.lower.z); 6199 pCoor[1].set(box.upper.x, box.upper.y, box.lower.z); 6200 pCoor[2].set(box.upper.x, box.upper.y, box.upper.z); 6201 pCoor[3].set(box.upper.x, box.lower.y, box.upper.z); 6202 if (intersectPolygon(pCoor, coordinates)) { 6203 if (dist != null) { 6204 computeMinDistance(pCoor, box.getCenter(), 6205 null, 6206 dist, iPnt); 6207 } 6208 return true; 6209 } 6210 6211 // bottom plane. 6212 pCoor[0].set(box.upper.x, box.lower.y, box.upper.z); 6213 pCoor[1].set(box.lower.x, box.lower.y, box.upper.z); 6214 pCoor[2].set(box.lower.x, box.lower.y, box.lower.z); 6215 pCoor[3].set(box.upper.x, box.lower.y, box.lower.z); 6216 if (intersectPolygon(pCoor, coordinates)) { 6217 if (dist != null) { 6218 computeMinDistance(pCoor, box.getCenter(), 6219 null, 6220 dist, iPnt); 6221 } 6222 return true; 6223 } 6224 // top plane. 6225 pCoor[0].set(box.upper.x, box.upper.y, box.upper.z); 6226 pCoor[1].set(box.upper.x, box.upper.y, box.lower.z); 6227 pCoor[2].set(box.lower.x, box.upper.y, box.lower.z); 6228 pCoor[3].set(box.lower.x, box.upper.y, box.upper.z); 6229 if (intersectPolygon(pCoor, coordinates)) { 6230 if (dist != null) { 6231 computeMinDistance(pCoor, box.getCenter(), 6232 null, 6233 dist, iPnt); 6234 } 6235 return true; 6236 } 6237 6238 // front plane. 6239 pCoor[0].set(box.upper.x, box.upper.y, box.upper.z); 6240 pCoor[1].set(box.lower.x, box.upper.y, box.upper.z); 6241 pCoor[2].set(box.lower.x, box.lower.y, box.upper.z); 6242 pCoor[3].set(box.upper.x, box.lower.y, box.upper.z); 6243 if (intersectPolygon(pCoor, coordinates)) { 6244 if (dist != null) { 6245 computeMinDistance(pCoor, box.getCenter(), 6246 null, 6247 dist, iPnt); 6248 } 6249 return true; 6250 } 6251 6252 // back plane. 6253 pCoor[0].set(box.upper.x, box.upper.y, box.lower.z); 6254 pCoor[1].set(box.upper.x, box.lower.y, box.lower.z); 6255 pCoor[2].set(box.lower.x, box.lower.y, box.lower.z); 6256 pCoor[3].set(box.lower.x, box.upper.y, box.lower.z); 6257 if (intersectPolygon(pCoor, coordinates)) { 6258 if (dist != null) { 6259 computeMinDistance(pCoor, box.getCenter(), 6260 null, 6261 dist, iPnt); 6262 } 6263 return true; 6264 } 6265 return false; 6266 } 6267 6268 intersectBoundingSphere(Point3d coordinates[], BoundingSphere sphere, double dist[], Point3d iPnt)6269 boolean intersectBoundingSphere(Point3d coordinates[], 6270 BoundingSphere sphere, 6271 double dist[], 6272 Point3d iPnt) 6273 { 6274 int i, j; 6275 Vector3d tempV3D = new Vector3d(); 6276 boolean esFlag; 6277 6278 //Do trivial vertex test. 6279 6280 for (i=0; i<coordinates.length; i++) { 6281 tempV3D.x = coordinates[i].x - sphere.center.x; 6282 tempV3D.y = coordinates[i].y - sphere.center.y; 6283 tempV3D.z = coordinates[i].z - sphere.center.z; 6284 6285 if (tempV3D.length() <= sphere.radius) { 6286 // We're done! It's inside the boundingSphere. 6287 if (dist != null) { 6288 computeMinDistance(coordinates, 6289 sphere.getCenter(), 6290 null, dist, iPnt); 6291 } 6292 6293 return true; 6294 } 6295 } 6296 6297 for (i=0; i<coordinates.length; i++) { 6298 if (i < (coordinates.length-1)) 6299 esFlag = edgeIntersectSphere(sphere, coordinates[i], 6300 coordinates[i+1]); 6301 else 6302 esFlag = edgeIntersectSphere(sphere, coordinates[i], 6303 coordinates[0]); 6304 if (esFlag == true) { 6305 if (dist != null) { 6306 computeMinDistance(coordinates, 6307 sphere.getCenter(), 6308 null, 6309 dist, iPnt); 6310 } 6311 6312 return true; 6313 } 6314 } 6315 6316 6317 if (coordinates.length < 3) { 6318 return false; // We're done with line. 6319 } 6320 6321 // Find rho. 6322 // Compute plane normal. 6323 Vector3d vec0 = new Vector3d(); // Edge vector from point 0 to point 1; 6324 Vector3d vec1 = new Vector3d(); // Edge vector from point 0 to point 2 or 3; 6325 Vector3d pNrm = new Vector3d(); 6326 Vector3d pa = new Vector3d(); 6327 Point3d q = new Point3d(); 6328 double nLenSq, pqLen, pNrmDotPa, tq; 6329 6330 // compute plane normal for coordinates. 6331 for(i=0; i<coordinates.length-1;) { 6332 vec0.x = coordinates[i+1].x - coordinates[i].x; 6333 vec0.y = coordinates[i+1].y - coordinates[i].y; 6334 vec0.z = coordinates[i+1].z - coordinates[i++].z; 6335 if(vec0.length() > 0.0) 6336 break; 6337 } 6338 6339 for(j=i; j<coordinates.length-1; j++) { 6340 vec1.x = coordinates[j+1].x - coordinates[j].x; 6341 vec1.y = coordinates[j+1].y - coordinates[j].y; 6342 vec1.z = coordinates[j+1].z - coordinates[j].z; 6343 if(vec1.length() > 0.0) 6344 break; 6345 } 6346 6347 if(j == (coordinates.length-1)) { 6348 // System.err.println("(1) Degenerate polygon."); 6349 return false; // Degenerate polygon. 6350 } 6351 6352 /* 6353 for(i=0; i<coordinates.length; i++) 6354 System.err.println("coordinates P" + i + " " + coordinates[i]); 6355 for(i=0; i<coord2.length; i++) 6356 System.err.println("coord2 P" + i + " " + coord2[i]); 6357 */ 6358 6359 pNrm.cross(vec0,vec1); 6360 6361 nLenSq = pNrm.lengthSquared(); 6362 if( nLenSq == 0.0) { 6363 // System.err.println("(2) Degenerate polygon."); 6364 return false; // Degenerate polygon. 6365 } 6366 6367 pa.x = coordinates[0].x - sphere.center.x; 6368 pa.y = coordinates[0].y - sphere.center.y; 6369 pa.z = coordinates[0].z - sphere.center.z; 6370 6371 pNrmDotPa = pNrm.dot(pa); 6372 6373 pqLen = Math.sqrt(pNrmDotPa * pNrmDotPa/ nLenSq); 6374 6375 if(pqLen > sphere.radius) { 6376 return false; 6377 } 6378 6379 tq = pNrmDotPa / nLenSq; 6380 6381 q.x = sphere.center.x + tq * pNrm.x; 6382 q.y = sphere.center.y + tq * pNrm.y; 6383 q.z = sphere.center.z + tq * pNrm.z; 6384 6385 // PolyPnt2D Test. 6386 if (pointIntersectPolygon2D( pNrm, coordinates, q)) { 6387 if (dist != null) { 6388 computeMinDistance(coordinates, 6389 sphere.getCenter(), 6390 pNrm, 6391 dist, iPnt); 6392 } 6393 return true; 6394 } 6395 return false; 6396 6397 } 6398 6399 intersectBoundingPolytope(Point3d coordinates[], BoundingPolytope polytope, double dist[], Point3d iPnt)6400 boolean intersectBoundingPolytope(Point3d coordinates[], 6401 BoundingPolytope polytope, 6402 double dist[], 6403 Point3d iPnt) 6404 { 6405 boolean debug = false; 6406 6407 Point4d tP4d = new Point4d(); 6408 6409 // this is a multiplier to the halfplane distance coefficients 6410 double distanceSign = -1.0; 6411 6412 if(coordinates.length == 2) { 6413 // we'll handle line separately. 6414 if (polytope.intersect( coordinates[0], 6415 coordinates[1], tP4d)) { 6416 if (dist != null) { 6417 iPnt.x = tP4d.x; 6418 iPnt.y = tP4d.y; 6419 iPnt.z = tP4d.z; 6420 Point3d pc = polytope.getCenter(); 6421 double x = iPnt.x - pc.x; 6422 double y = iPnt.y - pc.y; 6423 double z = iPnt.z - pc.z; 6424 dist[0] = Math.sqrt(x*x + y*y + z*z); 6425 } 6426 return true; 6427 } 6428 return false; 6429 } 6430 6431 // It is a triangle or a quad. 6432 6433 // first test to see if any of the coordinates are all inside of the 6434 // intersection polytope's half planes 6435 // essentially do a matrix multiply of the constraintMatrix K*3 with 6436 // the input coordinates 3*1 = K*1 vector 6437 6438 if (debug) { 6439 System.err.println("The value of the input vertices are: "); 6440 for(int i=0; i < coordinates.length; i++) { 6441 System.err.println("The " +i+ " th vertex is: " + coordinates[i]); 6442 } 6443 6444 System.err.println("The value of the input bounding Polytope's planes ="); 6445 for(int i=0; i < polytope.planes.length; i++) { 6446 System.err.println("The " +i+ " th plane is: " + polytope.planes[i]); 6447 } 6448 6449 } 6450 6451 // the direction for the intersection cost function 6452 double centers[] = new double[4]; 6453 centers[0] = 0.8; centers[1] = 0.9; centers[2] = 1.1; centers[3] = 1.2; 6454 6455 boolean intersection = true; 6456 boolean PreTest = false; 6457 6458 if(PreTest) { 6459 // for each coordinate, test it with each half plane 6460 for( int i=0; i < coordinates.length; i++) { 6461 for (int j=0; j < polytope.planes.length; j++) { 6462 if ( ( polytope.planes[j].x * coordinates[i].x + 6463 polytope.planes[j].y * coordinates[i].y + 6464 polytope.planes[j].z*coordinates[i].z) <= 6465 (distanceSign)*polytope.planes[j].w){ 6466 // the point satisfies this particular hyperplane 6467 intersection = true; 6468 } else { 6469 // the point fails this hyper plane try with a new hyper plane 6470 intersection = false; 6471 break; 6472 } 6473 } 6474 if(intersection) { 6475 // a point was found to be completely inside the bounding hull 6476 if (dist != null) { 6477 computeMinDistance(coordinates, 6478 polytope.getCenter(), 6479 null, 6480 dist, iPnt); 6481 } 6482 return true; 6483 } 6484 } 6485 } // end of pretest 6486 6487 // at this point all points are outside of the bounding hull 6488 // build the problem tableau for the linear program 6489 6490 int numberCols = polytope.planes.length + 2 + coordinates.length + 1; 6491 int numberRows = 1 + coordinates.length; 6492 6493 double problemTableau[][] = new double[numberRows][numberCols]; 6494 6495 // compute -Mtrans = -A*P 6496 6497 for( int i = 0; i < polytope.planes.length; i++) { 6498 for( int j=0; j < coordinates.length; j++) { 6499 problemTableau[j][i] = (-1.0)* (polytope.planes[i].x*coordinates[j].x+ 6500 polytope.planes[i].y*coordinates[j].y+ 6501 polytope.planes[i].z*coordinates[j].z); 6502 } 6503 } 6504 6505 // add the other rows 6506 for(int i = 0; i < coordinates.length; i++) { 6507 problemTableau[i][polytope.planes.length] = -1.0; 6508 problemTableau[i][polytope.planes.length + 1] = 1.0; 6509 6510 for(int j=0; j < coordinates.length; j++) { 6511 if ( i==j ) { 6512 problemTableau[i][j + polytope.planes.length + 2] = 1.0; 6513 } else { 6514 problemTableau[i][j + polytope.planes.length + 2] = 0.0; 6515 } 6516 6517 // place the last column elements the Ci's 6518 problemTableau[i][numberCols - 1] = centers[i]; 6519 } 6520 } 6521 6522 // place the final rows value 6523 for(int j = 0; j < polytope.planes.length; j++) { 6524 problemTableau[numberRows - 1][j] = 6525 (distanceSign)*polytope.planes[j].w; 6526 } 6527 problemTableau[numberRows - 1][polytope.planes.length] = 1.0; 6528 problemTableau[numberRows - 1][polytope.planes.length+1] = -1.0; 6529 for(int j = 0; j < coordinates.length; j++) { 6530 problemTableau[numberRows - 1][polytope.planes.length+2+j] = 0.0; 6531 } 6532 6533 if(debug) { 6534 System.err.println("The value of the problem tableau is: " ); 6535 for(int i=0; i < problemTableau.length; i++) { 6536 for(int j=0; j < problemTableau[0].length; j++) { 6537 System.err.print(problemTableau[i][j] + " "); 6538 } 6539 System.err.println(); 6540 } 6541 } 6542 6543 double distance = generalStandardSimplexSolver(problemTableau, 6544 Float.NEGATIVE_INFINITY); 6545 if(debug) { 6546 System.err.println("The value returned by the general standard simplex = " + 6547 distance); 6548 } 6549 if (distance == Float.POSITIVE_INFINITY) { 6550 return false; 6551 } 6552 if (dist != null) { 6553 computeMinDistance(coordinates, 6554 polytope.getCenter(), 6555 null, 6556 dist, iPnt); 6557 } 6558 return true; 6559 6560 } 6561 6562 6563 // optimized version using arrays of doubles, but using the standard simplex 6564 // method to solve the LP tableau. This version has not been optimized to 6565 // work with a particular size input tableau and is much slower than some 6566 // of the other variants...supposedly generalStandardSimplexSolver(double problemTableau[][], double stopingValue)6567 double generalStandardSimplexSolver(double problemTableau[][], 6568 double stopingValue) { 6569 boolean debug = false; 6570 int numRow = problemTableau.length; 6571 int numCol = problemTableau[0].length; 6572 boolean optimal = false; 6573 int i, pivotRowIndex, pivotColIndex; 6574 double maxElement, element, endElement, ratio, prevRatio; 6575 int count = 0; 6576 double multiplier; 6577 6578 if(debug) { 6579 System.err.println("The number of rows is : " + numRow); 6580 System.err.println("The number of columns is : " + numCol); 6581 } 6582 6583 // until the optimal solution is found continue to do 6584 // iterations of the simplex method 6585 while(!optimal) { 6586 6587 if(debug) { 6588 System.err.println("input problem tableau is:"); 6589 for(int k=0; k < numRow; k++) { 6590 for(int j=0; j < numCol; j++) { 6591 System.err.println("kth, jth value is:" +k+" "+j+" : " + 6592 problemTableau[k][j]); 6593 } 6594 } 6595 } 6596 6597 // test to see if the current solution is optimal 6598 // check all bottom row elements except the right most one and 6599 // if all positive or zero its optimal 6600 for(i = 0, maxElement = 0, pivotColIndex = -1; i < numCol - 1; i++) { 6601 // a bottom row element 6602 element = problemTableau[numRow - 1][i]; 6603 if( element < maxElement) { 6604 maxElement = element; 6605 pivotColIndex = i; 6606 } 6607 } 6608 6609 // if there is no negative non-zero element then we 6610 // have found an optimal solution (the last row of the tableau) 6611 if(pivotColIndex == -1) { 6612 // found an optimal solution 6613 //System.err.println("Found an optimal solution"); 6614 optimal = true; 6615 } 6616 6617 //System.err.println("The value of maxElement is:" + maxElement); 6618 6619 if(!optimal) { 6620 // Case when the solution is not optimal but not known to be 6621 // either unbounded or infeasable 6622 6623 // from the above we have found the maximum negative element in 6624 // bottom row, we have also found the column for this value 6625 // the pivotColIndex represents this 6626 6627 // initialize the values for the algorithm, -1 for pivotRowIndex 6628 // indicates no solution 6629 6630 prevRatio = Float.POSITIVE_INFINITY; 6631 ratio = 0.0; 6632 pivotRowIndex = -1; 6633 6634 // note if all of the elements in the pivot column are zero or 6635 // negative the problem is unbounded. 6636 for(i = 0; i < numRow - 1; i++) { 6637 element = problemTableau[i][pivotColIndex]; // r value 6638 endElement = problemTableau[i][numCol-1]; // s value 6639 6640 // pivot according to the rule that we want to choose the row 6641 // with smallest s/r ratio see third case 6642 // currently we ignore valuse of r==0 (case 1) and cases where the 6643 // ratio is negative, i.e. either r or s are negative (case 2) 6644 if(element == 0) { 6645 if(debug) { 6646 System.err.println("Division by zero has occurred"); 6647 System.err.println("Within the linear program solver"); 6648 System.err.println("Ignoring the zero as a potential pivot"); 6649 } 6650 } else if ( (element < 0.0) || (endElement < 0.0) ){ 6651 if(debug) { 6652 System.err.println("Ignoring cases where element is negative"); 6653 System.err.println("The value of element is: " + element); 6654 System.err.println("The value of end Element is: " + endElement); 6655 } 6656 } else { 6657 ratio = endElement/element; // should be s/r 6658 if(debug) { 6659 System.err.println("The value of element is: " + element); 6660 System.err.println("The value of endElement is: " + endElement); 6661 System.err.println("The value of ratio is: " + ratio); 6662 System.err.println("The value of prevRatio is: " + prevRatio); 6663 System.err.println("Value of ratio <= prevRatio is :" + 6664 (ratio <= prevRatio)); 6665 } 6666 if(ratio <= prevRatio) { 6667 if(debug) { 6668 System.err.println("updating prevRatio with ratio"); 6669 } 6670 prevRatio = ratio; 6671 pivotRowIndex = i; 6672 } 6673 } 6674 } 6675 6676 // if the pivotRowIndex is still -1 then we know the pivotColumn 6677 // has no viable pivot points and the solution is unbounded or 6678 // infeasable (all pivot elements were either zero or negative or 6679 // the right most value was negative (the later shouldn't happen?) 6680 if(pivotRowIndex == -1) { 6681 if(debug) { 6682 System.err.println("UNABLE TO FIND SOLUTION"); 6683 System.err.println("The system is infeasable or unbounded"); 6684 } 6685 return(Float.POSITIVE_INFINITY); 6686 } 6687 6688 // we now have the pivot row and col all that remains is 6689 // to divide through by this value and subtract the appropriate 6690 // multiple of the pivot row from all other rows to obtain 6691 // a tableau which has a column of all zeros and one 1 in the 6692 // intersection of pivot row and col 6693 6694 // divide through by the pivot value 6695 double pivotValue = problemTableau[pivotRowIndex][pivotColIndex]; 6696 6697 if(debug) { 6698 System.err.println("The value of row index is: " + pivotRowIndex); 6699 System.err.println("The value of col index is: " + pivotColIndex); 6700 System.err.println("The value of pivotValue is: " + pivotValue); 6701 } 6702 // divide through by s on the pivot row to obtain a 1 in pivot col 6703 for(i = 0; i < numCol; i++) { 6704 problemTableau[pivotRowIndex][i] = 6705 problemTableau[pivotRowIndex][i] / pivotValue; 6706 } 6707 6708 // subtract appropriate multiple of pivot row from all other rows 6709 // to zero out all rows except the final row and the pivot row 6710 for(i = 0; i < numRow; i++) { 6711 if(i != pivotRowIndex) { 6712 multiplier = problemTableau[i][pivotColIndex]; 6713 for(int j=0; j < numCol; j++) { 6714 problemTableau[i][j] = problemTableau[i][j] - 6715 multiplier * problemTableau[pivotRowIndex][j]; 6716 } 6717 } 6718 } 6719 } 6720 // case when the element is optimal 6721 } 6722 return(problemTableau[numRow - 1][numCol - 1]); 6723 } 6724 6725 6726 edgeIntersectSphere(BoundingSphere sphere, Point3d start, Point3d end)6727 boolean edgeIntersectSphere(BoundingSphere sphere, Point3d start, 6728 Point3d end) 6729 { 6730 double abLenSq, acLenSq, apLenSq, abDotAp, radiusSq; 6731 Vector3d ab = new Vector3d(); 6732 Vector3d ap = new Vector3d(); 6733 6734 ab.x = end.x - start.x; 6735 ab.y = end.y - start.y; 6736 ab.z = end.z - start.z; 6737 6738 ap.x = sphere.center.x - start.x; 6739 ap.y = sphere.center.y - start.y; 6740 ap.z = sphere.center.z - start.z; 6741 6742 abDotAp = ab.dot(ap); 6743 6744 if(abDotAp < 0.0) { 6745 return false; // line segment points away from sphere. 6746 } 6747 6748 abLenSq = ab.lengthSquared(); 6749 acLenSq = abDotAp * abDotAp / abLenSq; 6750 6751 if(acLenSq < abLenSq) { 6752 return false; // C doesn't lies between end points of edge. 6753 } 6754 6755 radiusSq = sphere.radius * sphere.radius; 6756 apLenSq = ap.lengthSquared(); 6757 6758 if((apLenSq - acLenSq) <= radiusSq) { 6759 return true; 6760 } 6761 6762 return false; 6763 6764 } 6765 6766 det2D(Point2d a, Point2d b, Point2d p)6767 double det2D(Point2d a, Point2d b, Point2d p) 6768 { 6769 return (((p).x - (a).x) * ((a).y - (b).y) + 6770 ((a).y - (p).y) * ((a).x - (b).x)); 6771 } 6772 6773 // Assume coord is CCW. pointIntersectPolygon2D(Vector3d normal, Point3d[] coord, Point3d point)6774 boolean pointIntersectPolygon2D(Vector3d normal, Point3d[] coord, 6775 Point3d point) 6776 { 6777 6778 double absNrmX, absNrmY, absNrmZ; 6779 Point2d coord2D[] = new Point2d[coord.length]; 6780 Point2d pnt = new Point2d(); 6781 6782 int i, j, axis; 6783 6784 // Project 3d points onto 2d plane. 6785 // Note : Area of polygon is not preserve in this projection, but 6786 // it doesn't matter here. 6787 6788 // Find the axis of projection. 6789 absNrmX = Math.abs(normal.x); 6790 absNrmY = Math.abs(normal.y); 6791 absNrmZ = Math.abs(normal.z); 6792 6793 if(absNrmX > absNrmY) 6794 axis = 0; 6795 else 6796 axis = 1; 6797 6798 if(axis == 0) { 6799 if(absNrmX < absNrmZ) 6800 axis = 2; 6801 } 6802 else if(axis == 1) { 6803 if(absNrmY < absNrmZ) 6804 axis = 2; 6805 } 6806 6807 // System.err.println("Normal " + normal + " axis " + axis ); 6808 6809 for(i=0; i<coord.length; i++) { 6810 coord2D[i] = new Point2d(); 6811 6812 switch (axis) { 6813 case 0: 6814 coord2D[i].x = coord[i].y; 6815 coord2D[i].y = coord[i].z; 6816 break; 6817 6818 case 1: 6819 coord2D[i].x = coord[i].x; 6820 coord2D[i].y = coord[i].z; 6821 break; 6822 6823 case 2: 6824 coord2D[i].x = coord[i].x; 6825 coord2D[i].y = coord[i].y; 6826 break; 6827 } 6828 6829 // System.err.println("i " + i + " u " + uCoor[i] + " v " + vCoor[i]); 6830 } 6831 6832 6833 switch (axis) { 6834 case 0: 6835 pnt.x = point.y; 6836 pnt.y = point.z; 6837 break; 6838 6839 case 1: 6840 pnt.x = point.x; 6841 pnt.y = point.z; 6842 break; 6843 6844 case 2: 6845 pnt.x = point.x; 6846 pnt.y = point.y; 6847 break; 6848 } 6849 6850 // Do determinant test. 6851 for(j=0; j<coord.length; j++) { 6852 if(j<(coord.length-1)) 6853 if(det2D(coord2D[j], coord2D[j+1], pnt)>0.0) 6854 ; 6855 else 6856 return false; 6857 else 6858 if(det2D(coord2D[j], coord2D[0], pnt)>0.0) 6859 ; 6860 else 6861 return false; 6862 } 6863 6864 return true; 6865 6866 } 6867 6868 edgeIntersectPlane(Vector3d normal, Point3d pnt, Point3d start, Point3d end, Point3d iPnt)6869 boolean edgeIntersectPlane(Vector3d normal, Point3d pnt, Point3d start, 6870 Point3d end, Point3d iPnt) 6871 { 6872 6873 Vector3d tempV3d = new Vector3d(); 6874 Vector3d direction = new Vector3d(); 6875 double pD, pNrmDotrDir, tr; 6876 6877 // Compute plane D. 6878 tempV3d.set((Tuple3d) pnt); 6879 pD = normal.dot(tempV3d); 6880 6881 direction.x = end.x - start.x; 6882 direction.y = end.y - start.y; 6883 direction.z = end.z - start.z; 6884 6885 pNrmDotrDir = normal.dot(direction); 6886 6887 // edge is parallel to plane. 6888 if(pNrmDotrDir== 0.0) { 6889 // System.err.println("Edge is parallel to plane."); 6890 return false; 6891 } 6892 6893 tempV3d.set((Tuple3d) start); 6894 6895 tr = (pD - normal.dot(tempV3d))/ pNrmDotrDir; 6896 6897 // Edge intersects the plane behind the edge's start. 6898 // or exceed the edge's length. 6899 if((tr < 0.0 ) || (tr > 1.0 )) { 6900 // System.err.println("Edge intersects the plane behind the start or exceed end."); 6901 return false; 6902 } 6903 6904 iPnt.x = start.x + tr * direction.x; 6905 iPnt.y = start.y + tr * direction.y; 6906 iPnt.z = start.z + tr * direction.z; 6907 6908 return true; 6909 6910 } 6911 6912 // Assume coord is CCW. edgeIntersectPolygon2D(Vector3d normal, Point3d[] coord, Point3d[] seg)6913 boolean edgeIntersectPolygon2D(Vector3d normal, Point3d[] coord, 6914 Point3d[] seg) 6915 { 6916 6917 double absNrmX, absNrmY, absNrmZ; 6918 Point2d coord2D[] = new Point2d[coord.length]; 6919 Point2d seg2D[] = new Point2d[2]; 6920 6921 int i, j, axis; 6922 6923 // Project 3d points onto 2d plane. 6924 // Note : Area of polygon is not preserve in this projection, but 6925 // it doesn't matter here. 6926 6927 // Find the axis of projection. 6928 absNrmX = Math.abs(normal.x); 6929 absNrmY = Math.abs(normal.y); 6930 absNrmZ = Math.abs(normal.z); 6931 6932 if(absNrmX > absNrmY) 6933 axis = 0; 6934 else 6935 axis = 1; 6936 6937 if(axis == 0) { 6938 if(absNrmX < absNrmZ) 6939 axis = 2; 6940 } 6941 else if(axis == 1) { 6942 if(absNrmY < absNrmZ) 6943 axis = 2; 6944 } 6945 6946 // System.err.println("Normal " + normal + " axis " + axis ); 6947 6948 for(i=0; i<coord.length; i++) { 6949 coord2D[i] = new Point2d(); 6950 6951 switch (axis) { 6952 case 0: 6953 coord2D[i].x = coord[i].y; 6954 coord2D[i].y = coord[i].z; 6955 break; 6956 6957 case 1: 6958 coord2D[i].x = coord[i].x; 6959 coord2D[i].y = coord[i].z; 6960 break; 6961 6962 case 2: 6963 coord2D[i].x = coord[i].x; 6964 coord2D[i].y = coord[i].y; 6965 break; 6966 } 6967 6968 // System.err.println("i " + i + " u " + uCoor[i] + " v " + vCoor[i]); 6969 } 6970 6971 for(i=0; i<2; i++) { 6972 seg2D[i] = new Point2d(); 6973 switch (axis) { 6974 case 0: 6975 seg2D[i].x = seg[i].y; 6976 seg2D[i].y = seg[i].z; 6977 break; 6978 6979 case 1: 6980 seg2D[i].x = seg[i].x; 6981 seg2D[i].y = seg[i].z; 6982 break; 6983 6984 case 2: 6985 seg2D[i].x = seg[i].x; 6986 seg2D[i].y = seg[i].y; 6987 break; 6988 } 6989 6990 // System.err.println("i " + i + " u " + uSeg[i] + " v " + vSeg[i]); 6991 } 6992 6993 // Do determinant test. 6994 boolean pntTest[][] = new boolean[2][coord.length]; 6995 boolean testFlag; 6996 6997 for(j=0; j<coord.length; j++) { 6998 for(i=0; i<2; i++) { 6999 if(j<(coord.length-1)) 7000 pntTest[i][j] = (det2D(coord2D[j], coord2D[j+1], seg2D[i])<0.0); 7001 else 7002 pntTest[i][j] = (det2D(coord2D[j], coord2D[0], seg2D[i])<0.0); 7003 } 7004 7005 if((pntTest[0][j]==false) && (pntTest[1][j]==false)) 7006 return false; 7007 } 7008 7009 testFlag = true; 7010 for(i=0; i<coord.length; i++) { 7011 if(pntTest[0][i]==false) { 7012 testFlag = false; 7013 break; 7014 } 7015 } 7016 7017 if(testFlag == true) 7018 return true; // start point is inside polygon. 7019 7020 testFlag = true; 7021 for(i=0; i<coord.length; i++) { 7022 if(pntTest[1][i]==false) { 7023 testFlag = false; 7024 break; 7025 } 7026 } 7027 7028 if(testFlag == true) 7029 return true; // end point is inside polygon. 7030 7031 7032 int cnt = 0; 7033 for(i=0; i<coord.length; i++) { 7034 if(det2D(seg2D[0], seg2D[1], coord2D[i])<0.0) 7035 cnt++; 7036 } 7037 7038 if((cnt==0)||(cnt==coord.length)) 7039 return false; 7040 7041 return true; 7042 7043 } 7044 7045 7046 // New stuffs ..... getCompValue(Point3d v, int i)7047 double getCompValue(Point3d v, int i) { 7048 switch (i) { 7049 case 0: return v.x; 7050 case 1: return v.y; 7051 } 7052 // Has to return something, so set the default to z component. 7053 return v.z; 7054 } 7055 getCompValue(Point3d v0, Point3d v1, int i)7056 double getCompValue(Point3d v0, Point3d v1, int i) { 7057 switch (i) { 7058 case 0: return (v0.x - v1.x); 7059 case 1: return (v0.y - v1.y); 7060 } 7061 // Has to return some, so set the default to z component. 7062 return (v0.z - v1.z); 7063 } 7064 7065 pointInTri(Point3d v0, Point3d u0, Point3d u1, Point3d u2, Vector3d normal)7066 boolean pointInTri(Point3d v0, Point3d u0, Point3d u1, Point3d u2, 7067 Vector3d normal) { 7068 7069 double nAbsX, nAbsY, nAbsZ; 7070 int i0, i1; 7071 7072 // first project onto an axis-aligned plane, that maximizes the area 7073 // of the triangles, compute indices i0, i1. 7074 nAbsX = Math.abs(normal.x); 7075 nAbsY = Math.abs(normal.y); 7076 nAbsZ = Math.abs(normal.z); 7077 7078 if (nAbsX > nAbsY) { 7079 if(nAbsX > nAbsZ) { 7080 i0 = 1; // nAbsX is greatest. 7081 i1 = 2; 7082 } 7083 else { 7084 i0 = 0; // nAbsZ is greatest. 7085 i1 = 1; 7086 } 7087 } else { // nAbsX <= nAbsY 7088 if(nAbsZ > nAbsY) { 7089 i0 = 0; // nAbsZ is greatest. 7090 i1 = 1; 7091 } 7092 else { 7093 i0 = 0; // nAbsY is greatest. 7094 i1 = 2; 7095 } 7096 } 7097 return pointInTri(v0, u0, u1, u2, i0, i1); 7098 } 7099 pointInTri(Point3d v0, Point3d u0, Point3d u1, Point3d u2, int i0, int i1)7100 boolean pointInTri(Point3d v0, Point3d u0, Point3d u1, Point3d u2, 7101 int i0, int i1) { 7102 7103 double a, b, c, d0, d1, d2; 7104 // is T1 completely inside T2 ? 7105 // check if v0 is inside tri(u0,u1,u2) 7106 7107 a = getCompValue(u1, u0, i1); 7108 b = -(getCompValue(u1, u0, i0)); 7109 c = -a * getCompValue(u0, i0) - b * getCompValue(u0, i1); 7110 d0 = a * getCompValue(v0, i0) + b * getCompValue(v0, i1) + c; 7111 7112 a = getCompValue(u2, u1, i1); 7113 b = -(getCompValue(u2, u1, i0)); 7114 c = -a * getCompValue(u1, i0) - b * getCompValue(u1, i1); 7115 d1 = a * getCompValue(v0, i0) + b * getCompValue(v0, i1) + c; 7116 7117 a = getCompValue(u0, u2, i1); 7118 b = -(getCompValue(u0, u2, i0)); 7119 c = -a * getCompValue(u2, i0) - b * getCompValue(u2, i1); 7120 d2 = a * getCompValue(v0, i0) + b * getCompValue(v0, i1) + c; 7121 7122 if(d0*d1>0.0) { 7123 if(d0*d2>0.0) { 7124 return true; 7125 } 7126 } 7127 return false; 7128 } 7129 7130 7131 // this edge to edge test is based on Franlin Antonio's gem: 7132 // "Faster line segment intersection", in Graphics Gems III, pp 199-202 edgeAgainstEdge(Point3d v0, Point3d u0, Point3d u1, double aX, double aY, int i0, int i1)7133 boolean edgeAgainstEdge(Point3d v0, Point3d u0, Point3d u1, double aX, double aY, 7134 int i0, int i1) { 7135 double bX, bY, cX, cY, e, d, f; 7136 7137 bX = getCompValue(u0, u1,i0); 7138 bY = getCompValue(u0, u1, i1); 7139 cX = getCompValue(v0, u0, i0); 7140 cY = getCompValue(v0, u0, i1); 7141 7142 f = aY * bX - aX * bY; 7143 d = bY * cX - bX * cY; 7144 if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) { 7145 e = aX * cY - aY * cX; 7146 if(f>0) { 7147 if(e>=0 && e<=f) 7148 return true; 7149 } 7150 else { 7151 if(e<=0 && e>=f) 7152 return true; 7153 } 7154 } 7155 7156 return false; 7157 } 7158 7159 edgeAgainstTriEdges(Point3d v0, Point3d v1, Point3d u0, Point3d u1, Point3d u2, int i0, int i1)7160 boolean edgeAgainstTriEdges(Point3d v0, Point3d v1, Point3d u0, 7161 Point3d u1, Point3d u2, int i0, int i1) { 7162 double aX, aY; 7163 7164 // aX = v1[i0] - v0[i0]; 7165 // aY = v1[i1] - v0[i1]; 7166 aX = getCompValue(v1, v0, i0); 7167 aY = getCompValue(v1, v0, i1); 7168 7169 // test edge u0, u1 against v0, v1 7170 if(edgeAgainstEdge(v0, u0, u1, aX, aY, i0, i1)) 7171 return true; 7172 // test edge u1, u2 against v0, v1 7173 if(edgeAgainstEdge(v0, u1, u2, aX, aY, i0, i1)) 7174 return true; 7175 // test edge u2, u0 against v0, v1 7176 if(edgeAgainstEdge(v0, u2, u0, aX, aY, i0, i1)) 7177 return true; 7178 7179 return false; 7180 7181 } 7182 coplanarTriTri(Vector3d normal, Point3d v0, Point3d v1, Point3d v2, Point3d u0, Point3d u1, Point3d u2)7183 boolean coplanarTriTri(Vector3d normal, Point3d v0, Point3d v1, Point3d v2, 7184 Point3d u0, Point3d u1, Point3d u2) { 7185 7186 double nAbsX, nAbsY, nAbsZ; 7187 int i0, i1; 7188 7189 // first project onto an axis-aligned plane, that maximizes the area 7190 // of the triangles, compute indices i0, i1. 7191 nAbsX = Math.abs(normal.x); 7192 nAbsY = Math.abs(normal.y); 7193 nAbsZ = Math.abs(normal.z); 7194 7195 if(nAbsX > nAbsY) { 7196 if(nAbsX > nAbsZ) { 7197 i0 = 1; // nAbsX is greatest. 7198 i1 = 2; 7199 } 7200 else { 7201 i0 = 0; // nAbsZ is greatest. 7202 i1 = 1; 7203 } 7204 } 7205 else { // nAbsX <= nAbsY 7206 if(nAbsZ > nAbsY) { 7207 i0 = 0; // nAbsZ is greatest. 7208 i1 = 1; 7209 } 7210 else { 7211 i0 = 0; // nAbsY is greatest. 7212 i1 = 2; 7213 } 7214 } 7215 7216 // test all edges of triangle 1 against the edges of triangle 2 7217 if(edgeAgainstTriEdges(v0, v1, u0, u1, u2, i0, i1)) 7218 return true; 7219 7220 if(edgeAgainstTriEdges(v1, v2, u0, u1, u2, i0, i1)) 7221 return true; 7222 7223 if(edgeAgainstTriEdges(v2, v0, u0, u1, u2, i0, i1)) 7224 return true; 7225 7226 // finally, test if tri1 is totally contained in tri2 or vice versa. 7227 if(pointInTri(v0, u0, u1, u2, i0, i1)) 7228 return true; 7229 7230 if(pointInTri(u0, v0, v1, v2, i0, i1)) 7231 return true; 7232 7233 return false; 7234 } 7235 7236 7237 7238 7239 intersectTriPnt(Point3d v0, Point3d v1, Point3d v2, Point3d u)7240 boolean intersectTriPnt(Point3d v0, Point3d v1, Point3d v2, Point3d u) { 7241 7242 Vector3d e1 = new Vector3d(); 7243 Vector3d e2 = new Vector3d(); 7244 Vector3d n1 = new Vector3d(); 7245 Vector3d tempV3d = new Vector3d(); 7246 7247 double d1, du; 7248 7249 // compute plane equation of triange(coord1) 7250 e1.x = v1.x - v0.x; 7251 e1.y = v1.y - v0.y; 7252 e1.z = v1.z - v0.z; 7253 7254 e2.x = v2.x - v0.x; 7255 e2.y = v2.y - v0.y; 7256 e2.z = v2.z - v0.z; 7257 7258 n1.cross(e1,e2); 7259 7260 if(n1.length() == 0.0) { 7261 // System.err.println("(1) Degenerate triangle."); 7262 return false; // Degenerate triangle. 7263 } 7264 7265 tempV3d.set((Tuple3d) v0); 7266 d1 = - n1.dot(tempV3d); // plane equation 1: n1.x + d1 = 0 7267 7268 // put u to compute signed distance to the plane. 7269 tempV3d.set((Tuple3d) u); 7270 du = n1.dot(tempV3d) + d1; 7271 7272 // coplanarity robustness check 7273 if(Math.abs(du)<EPS) du = 0.0; 7274 7275 // no intersection occurs 7276 if(du != 0.0) { 7277 return false; 7278 } 7279 7280 double nAbsX, nAbsY, nAbsZ; 7281 int i0, i1; 7282 7283 // first project onto an axis-aligned plane, that maximizes the area 7284 // of the triangles, compute indices i0, i1. 7285 nAbsX = Math.abs(n1.x); 7286 nAbsY = Math.abs(n1.y); 7287 nAbsZ = Math.abs(n1.z); 7288 7289 if(nAbsX > nAbsY) { 7290 if(nAbsX > nAbsZ) { 7291 i0 = 1; // nAbsX is greatest. 7292 i1 = 2; 7293 } 7294 else { 7295 i0 = 0; // nAbsZ is greatest. 7296 i1 = 1; 7297 } 7298 } 7299 else { // nAbsX <= nAbsY 7300 if(nAbsZ > nAbsY) { 7301 i0 = 0; // nAbsZ is greatest. 7302 i1 = 1; 7303 } 7304 else { 7305 i0 = 0; // nAbsY is greatest. 7306 i1 = 2; 7307 } 7308 } 7309 7310 7311 // finally, test if u is totally contained in tri. 7312 if(pointInTri(u, v0, v1, v2, i0, i1)) { 7313 return true; 7314 } 7315 7316 return false; 7317 } 7318 7319 7320 /** 7321 * Return flag indicating whether two triangles intersect. This 7322 * uses Tomas Moller's code for fast triangle-triangle 7323 * intersection from his "Real-Time Rendering" book. 7324 * 7325 * The code is now divisionless. It tests for separating by planes 7326 * parallel to either triangle. If neither separate the 7327 * triangles, then two cases are considered. First case is if the 7328 * normals to the triangles are parallel. In that case, the 7329 * triangles are coplanar and a sequence of tests are made to see 7330 * if edges of each triangle intersect the other triangle. If the 7331 * normals are not parallel, then the two triangles can intersect 7332 * only on the line of intersection of the two planes. The 7333 * intervals of intersection of the triangles with the line of 7334 * intersection of the two planes are computed and tested for 7335 * overlap. 7336 */ intersectTriTri(Point3d v0, Point3d v1, Point3d v2, Point3d u0, Point3d u1, Point3d u2)7337 boolean intersectTriTri(Point3d v0, Point3d v1, Point3d v2, 7338 Point3d u0, Point3d u1, Point3d u2) { 7339 7340 // System.err.println("In intersectTriTri ..."); 7341 Vector3d e1 = new Vector3d(); 7342 Vector3d e2 = new Vector3d(); 7343 Vector3d n1 = new Vector3d(); 7344 Vector3d n2 = new Vector3d(); 7345 Vector3d tempV3d = new Vector3d(); 7346 7347 double d1, d2; 7348 double du0, du1, du2, dv0, dv1, dv2; 7349 double du0du1, du0du2, dv0dv1, dv0dv2; 7350 int index; 7351 double vp0=0.0, vp1=0.0, vp2=0.0; 7352 double up0=0.0, up1=0.0, up2=0.0; 7353 double bb, cc, max; 7354 7355 // compute plane equation of triange(coord1) 7356 e1.x = v1.x - v0.x; 7357 e1.y = v1.y - v0.y; 7358 e1.z = v1.z - v0.z; 7359 7360 e2.x = v2.x - v0.x; 7361 e2.y = v2.y - v0.y; 7362 e2.z = v2.z - v0.z; 7363 7364 n1.cross(e1,e2); 7365 7366 if(n1.length() == 0.0) { 7367 // System.err.println("(1) Degenerate triangle."); 7368 return false; // Degenerate triangle. 7369 } 7370 7371 tempV3d.set((Tuple3d) v0); 7372 d1 = - n1.dot(tempV3d); // plane equation 1: n1.x + d1 = 0 7373 7374 // put u0, u1, and u2 into plane equation 1 7375 // to compute signed distance to the plane. 7376 tempV3d.set((Tuple3d) u0); 7377 du0 = n1.dot(tempV3d) + d1; 7378 tempV3d.set((Tuple3d) u1); 7379 du1 = n1.dot(tempV3d) + d1; 7380 tempV3d.set((Tuple3d) u2); 7381 du2 = n1.dot(tempV3d) + d1; 7382 7383 // coplanarity robustness check 7384 if(Math.abs(du0)<EPS) du0 = 0.0; 7385 if(Math.abs(du1)<EPS) du1 = 0.0; 7386 if(Math.abs(du2)<EPS) du2 = 0.0; 7387 7388 du0du1 = du0 * du1; 7389 du0du2 = du0 * du2; 7390 7391 // same sign on all of them + not equal 0 ? 7392 // no intersection occurs 7393 if(du0du1>0.0 && du0du2>0.0) { 7394 // System.err.println("In intersectTriTri : du0du1>0.0 && du0du2>0.0"); 7395 return false; 7396 } 7397 7398 // compute plane of triangle(coord2) 7399 e1.x = u1.x - u0.x; 7400 e1.y = u1.y - u0.y; 7401 e1.z = u1.z - u0.z; 7402 7403 e2.x = u2.x - u0.x; 7404 e2.y = u2.y - u0.y; 7405 e2.z = u2.z - u0.z; 7406 7407 n2.cross(e1,e2); 7408 7409 if(n2.length() == 0.0) { 7410 // System.err.println("(2) Degenerate triangle."); 7411 return false; // Degenerate triangle. 7412 } 7413 7414 tempV3d.set((Tuple3d) u0); 7415 d2 = - n2.dot(tempV3d); // plane equation 2: n2.x + d2 = 0 7416 7417 // put v0, v1, and v2 into plane equation 2 7418 // to compute signed distance to the plane. 7419 tempV3d.set((Tuple3d) v0); 7420 dv0 = n2.dot(tempV3d) + d2; 7421 tempV3d.set((Tuple3d) v1); 7422 dv1 = n2.dot(tempV3d) + d2; 7423 tempV3d.set((Tuple3d) v2); 7424 dv2 = n2.dot(tempV3d) + d2; 7425 7426 // coplanarity robustness check 7427 if(Math.abs(dv0)<EPS) dv0 = 0.0; 7428 if(Math.abs(dv1)<EPS) dv1 = 0.0; 7429 if(Math.abs(dv2)<EPS) dv2 = 0.0; 7430 7431 dv0dv1 = dv0 * dv1; 7432 dv0dv2 = dv0 * dv2; 7433 7434 // same sign on all of them + not equal 0 ? 7435 // no intersection occurs 7436 if(dv0dv1>0.0 && dv0dv2>0.0) { 7437 // System.err.println("In intersectTriTri : dv0dv1>0.0 && dv0dv2>0.0"); 7438 return false; 7439 } 7440 // compute direction of intersection line. 7441 tempV3d.cross(n1, n2); 7442 7443 // compute and index to the largest component of tempV3d. 7444 max = Math.abs(tempV3d.x); 7445 index = 0; 7446 bb = Math.abs(tempV3d.y); 7447 cc = Math.abs(tempV3d.z); 7448 if(bb>max) { 7449 max=bb; 7450 index=1; 7451 } 7452 if(cc>max) { 7453 max=cc; 7454 index=2; 7455 } 7456 7457 // this is the simplified projection onto L. 7458 7459 switch (index) { 7460 case 0: 7461 vp0 = v0.x; 7462 vp1 = v1.x; 7463 vp2 = v2.x; 7464 7465 up0 = u0.x; 7466 up1 = u1.x; 7467 up2 = u2.x; 7468 break; 7469 case 1: 7470 vp0 = v0.y; 7471 vp1 = v1.y; 7472 vp2 = v2.y; 7473 7474 up0 = u0.y; 7475 up1 = u1.y; 7476 up2 = u2.y; 7477 break; 7478 case 2: 7479 vp0 = v0.z; 7480 vp1 = v1.z; 7481 vp2 = v2.z; 7482 7483 up0 = u0.z; 7484 up1 = u1.z; 7485 up2 = u2.z; 7486 break; 7487 } 7488 7489 // compute intereval for triangle 1. 7490 double a=0.0, b=0.0, c=0.0, x0=0.0, x1=0.0; 7491 if(dv0dv1>0.0) { 7492 // here we know that dv0dv2 <= 0.0 that is dv0 and dv1 are on the same side, 7493 // dv2 on the other side or on the plane. 7494 a = vp2; b = (vp0 - vp2) * dv2; c = (vp1 - vp2) * dv2; 7495 x0 = dv2 - dv0; x1 = dv2 - dv1; 7496 } 7497 else if(dv0dv2>0.0) { 7498 // here we know that dv0dv1<=0.0 7499 a = vp1; b = (vp0 - vp1) * dv1; c = (vp2 - vp1) * dv1; 7500 x0 = dv1 - dv0; x1 = dv1 - dv2; 7501 } 7502 else if((dv1*dv2>0.0) || (dv0 != 0.0)) { 7503 // here we know that dv0vd1<=0.0 or that dv0!=0.0 7504 a = vp0; b = (vp1 - vp0) * dv0; c = (vp2 - vp0) * dv0; 7505 x0 = dv0 - dv1; x1 = dv0 - dv2; 7506 } 7507 else if(dv1 != 0.0) { 7508 a = vp1; b = (vp0 - vp1) * dv1; c = (vp2 - vp1) * dv1; 7509 x0 = dv1 - dv0; x1 = dv1 - dv2; 7510 } 7511 else if(dv2 != 0.0) { 7512 a = vp2; b = (vp0 - vp2) * dv2; c = (vp1 - vp2) * dv2; 7513 x0 = dv2 - dv0; x1 = dv2 - dv1; 7514 } 7515 else { 7516 // triangles are coplanar 7517 boolean toreturn = coplanarTriTri(n1, v0, v1, v2, u0, u1, u2); 7518 return toreturn; 7519 } 7520 7521 7522 // compute intereval for triangle 2. 7523 double d=0.0, e=0.0, f=0.0, y0=0.0, y1=0.0; 7524 if(du0du1>0.0) { 7525 // here we know that du0du2 <= 0.0 that is du0 and du1 are on the same side, 7526 // du2 on the other side or on the plane. 7527 d = up2; e = (up0 - up2) * du2; f = (up1 - up2) * du2; 7528 y0 = du2 - du0; y1 = du2 - du1; 7529 } 7530 else if(du0du2>0.0) { 7531 // here we know that du0du1<=0.0 7532 d = up1; e = (up0 - up1) * du1; f = (up2 - up1) * du1; 7533 y0 = du1 - du0; y1 = du1 - du2; 7534 } 7535 else if((du1*du2>0.0) || (du0 != 0.0)) { 7536 // here we know that du0du1<=0.0 or that D0!=0.0 7537 d = up0; e = (up1 - up0) * du0; f = (up2 - up0) * du0; 7538 y0 = du0 - du1; y1 = du0 - du2; 7539 } 7540 else if(du1 != 0.0) { 7541 d = up1; e = (up0 - up1) * du1; f = (up2 - up1) * du1; 7542 y0 = du1 - du0; y1 = du1 - du2; 7543 } 7544 else if(du2 != 0.0) { 7545 d = up2; e = (up0 - up2) * du2; f = (up1 - up2) * du2; 7546 y0 = du2 - du0; y1 = du2 - du1; 7547 } 7548 else { 7549 // triangles are coplanar 7550 // System.err.println("In intersectTriTri : coplanarTriTri test 2"); 7551 boolean toreturn = coplanarTriTri(n2, v0, v1, v2, u0, u1, u2); 7552 return toreturn; 7553 } 7554 7555 double xx, yy, xxyy, tmp, isect1S, isect1E, isect2S, isect2E; 7556 xx = x0 * x1; 7557 yy = y0 * y1; 7558 xxyy = xx * yy; 7559 7560 tmp = a * xxyy; 7561 isect1S = tmp + b * x1 * yy; 7562 isect1E = tmp + c * x0 * yy; 7563 7564 tmp = d * xxyy; 7565 isect2S = tmp + e * y1 * xx; 7566 isect2E = tmp + f * y0 * xx; 7567 7568 // sort so that isect1S <= isect1E 7569 if(isect1S > isect1E) { 7570 tmp = isect1S; 7571 isect1S = isect1E; 7572 isect1E = tmp; 7573 } 7574 7575 // sort so that isect2S <= isect2E 7576 if(isect2S > isect2E) { 7577 tmp = isect2S; 7578 isect2S = isect2E; 7579 isect2E = tmp; 7580 } 7581 7582 if(isect1E<isect2S || isect2E<isect1S) { 7583 // System.err.println("In intersectTriTri :isect1E<isect2S || isect2E<isect1S"); 7584 // System.err.println("In intersectTriTri : return false"); 7585 return false; 7586 } 7587 7588 // System.err.println("In intersectTriTri : return true"); 7589 return true; 7590 7591 } 7592 7593 7594 intersectPolygon(Point3d coord1[], Point3d coord2[])7595 boolean intersectPolygon(Point3d coord1[], Point3d coord2[]) { 7596 int i, j; 7597 Vector3d vec0 = new Vector3d(); // Edge vector from point 0 to point 1; 7598 Vector3d vec1 = new Vector3d(); // Edge vector from point 0 to point 2 or 3; 7599 Vector3d pNrm = new Vector3d(); 7600 boolean epFlag; 7601 7602 7603 // compute plane normal for coord1. 7604 for(i=0; i<coord1.length-1;) { 7605 vec0.x = coord1[i+1].x - coord1[i].x; 7606 vec0.y = coord1[i+1].y - coord1[i].y; 7607 vec0.z = coord1[i+1].z - coord1[i++].z; 7608 if(vec0.length() > 0.0) 7609 break; 7610 } 7611 7612 for(j=i; j<coord1.length-1; j++) { 7613 vec1.x = coord1[j+1].x - coord1[j].x; 7614 vec1.y = coord1[j+1].y - coord1[j].y; 7615 vec1.z = coord1[j+1].z - coord1[j].z; 7616 if(vec1.length() > 0.0) 7617 break; 7618 } 7619 7620 if(j == (coord1.length-1)) { 7621 // System.err.println("(1) Degenerate polygon."); 7622 return false; // Degenerate polygon. 7623 } 7624 7625 /* 7626 for(i=0; i<coord1.length; i++) 7627 System.err.println("coord1 P" + i + " " + coord1[i]); 7628 for(i=0; i<coord2.length; i++) 7629 System.err.println("coord2 P" + i + " " + coord2[i]); 7630 */ 7631 7632 pNrm.cross(vec0,vec1); 7633 7634 if(pNrm.length() == 0.0) { 7635 // System.err.println("(2) Degenerate polygon."); 7636 return false; // Degenerate polygon. 7637 } 7638 7639 j = 0; 7640 Point3d seg[] = new Point3d[2]; 7641 seg[0] = new Point3d(); 7642 seg[1] = new Point3d(); 7643 7644 for(i=0; i<coord2.length; i++) { 7645 if(i < (coord2.length-1)) 7646 epFlag = edgeIntersectPlane(pNrm, coord1[0], coord2[i], 7647 coord2[i+1], seg[j]); 7648 else 7649 epFlag = edgeIntersectPlane(pNrm, coord1[0], coord2[i], 7650 coord2[0], seg[j]); 7651 if (epFlag) { 7652 if(++j>1) { 7653 break; 7654 } 7655 } 7656 } 7657 7658 if (j==0) { 7659 return false; 7660 } 7661 7662 if (coord2.length < 3) { 7663 boolean toreturn = pointIntersectPolygon2D(pNrm, coord1, seg[0]); 7664 return toreturn; 7665 } else { 7666 boolean toreturn = edgeIntersectPolygon2D(pNrm, coord1, seg); 7667 return toreturn; 7668 } 7669 } 7670 7671 7672 /** 7673 * Return true if triangle or quad intersects with ray and the 7674 * distance is stored in dist[0] and the intersect point in iPnt 7675 * (if iPnt is not null). 7676 */ intersectRay(Point3d coordinates[], PickRay ray, double dist[], Point3d iPnt)7677 boolean intersectRay(Point3d coordinates[], PickRay ray, double dist[], 7678 Point3d iPnt) { 7679 7680 return intersectRayOrSegment(coordinates, ray.direction, ray.origin, 7681 dist, iPnt, false); 7682 7683 } 7684 7685 /** 7686 * Return true if triangle or quad intersects with segment and 7687 * the distance is stored in dist[0]. 7688 */ intersectSegment( Point3d coordinates[], Point3d start, Point3d end, double dist[], Point3d iPnt )7689 boolean intersectSegment( Point3d coordinates[], Point3d start, Point3d end, 7690 double dist[], Point3d iPnt ) { 7691 boolean result; 7692 Vector3d direction = new Vector3d(); 7693 direction.x = end.x - start.x; 7694 direction.y = end.y - start.y; 7695 direction.z = end.z - start.z; 7696 result = intersectRayOrSegment(coordinates, direction, start, dist, iPnt, true); 7697 return result; 7698 } 7699 7700 7701 7702 /** 7703 * Return true if triangle or quad intersects with ray and the distance is 7704 * stored in pr. 7705 */ intersectRayOrSegment(Point3d coordinates[], Vector3d direction, Point3d origin, double dist[], Point3d iPnt, boolean isSegment)7706 boolean intersectRayOrSegment(Point3d coordinates[], 7707 Vector3d direction, Point3d origin, 7708 double dist[], Point3d iPnt, boolean isSegment) { 7709 Vector3d vec0, vec1, pNrm, tempV3d; 7710 vec0 = new Vector3d(); 7711 vec1 = new Vector3d(); 7712 pNrm = new Vector3d(); 7713 7714 double absNrmX, absNrmY, absNrmZ, pD = 0.0; 7715 double pNrmDotrDir = 0.0; 7716 7717 boolean isIntersect = false; 7718 int i, j, k=0, l = 0; 7719 7720 // Compute plane normal. 7721 for (i=0; i<coordinates.length; i++) { 7722 if (i != coordinates.length-1) { 7723 l = i+1; 7724 } else { 7725 l = 0; 7726 } 7727 vec0.x = coordinates[l].x - coordinates[i].x; 7728 vec0.y = coordinates[l].y - coordinates[i].y; 7729 vec0.z = coordinates[l].z - coordinates[i].z; 7730 if (vec0.length() > 0.0) { 7731 break; 7732 } 7733 } 7734 7735 7736 for (j=l; j<coordinates.length; j++) { 7737 if (j != coordinates.length-1) { 7738 k = j+1; 7739 } else { 7740 k = 0; 7741 } 7742 vec1.x = coordinates[k].x - coordinates[j].x; 7743 vec1.y = coordinates[k].y - coordinates[j].y; 7744 vec1.z = coordinates[k].z - coordinates[j].z; 7745 if (vec1.length() > 0.0) { 7746 break; 7747 } 7748 } 7749 7750 pNrm.cross(vec0,vec1); 7751 7752 if ((vec1.length() == 0) || (pNrm.length() == 0)) { 7753 // degenerate to line if vec0.length() == 0 7754 // or vec0.length > 0 and vec0 parallel to vec1 7755 k = (l == 0 ? coordinates.length-1: l-1); 7756 isIntersect = intersectLineAndRay(coordinates[l], 7757 coordinates[k], 7758 origin, 7759 direction, 7760 dist, 7761 iPnt); 7762 7763 // put the Vectors on the freelist 7764 return isIntersect; 7765 } 7766 7767 // It is possible that Quad is degenerate to Triangle 7768 // at this point 7769 7770 pNrmDotrDir = pNrm.dot(direction); 7771 7772 // Ray is parallel to plane. 7773 if (pNrmDotrDir == 0.0) { 7774 // Ray is parallel to plane 7775 // Check line/triangle intersection on plane. 7776 for (i=0; i < coordinates.length ;i++) { 7777 if (i != coordinates.length-1) { 7778 k = i+1; 7779 } else { 7780 k = 0; 7781 } 7782 if (intersectLineAndRay(coordinates[i], 7783 coordinates[k], 7784 origin, 7785 direction, 7786 dist, 7787 iPnt)) { 7788 isIntersect = true; 7789 break; 7790 } 7791 } 7792 return isIntersect; 7793 } 7794 7795 // Plane equation: (p - p0)*pNrm = 0 or p*pNrm = pD; 7796 tempV3d = new Vector3d(); 7797 tempV3d.set((Tuple3d) coordinates[0]); 7798 pD = pNrm.dot(tempV3d); 7799 tempV3d.set((Tuple3d) origin); 7800 7801 // Substitute Ray equation: 7802 // p = origin + pi.distance*direction 7803 // into the above Plane equation 7804 7805 dist[0] = (pD - pNrm.dot(tempV3d))/ pNrmDotrDir; 7806 7807 // Ray intersects the plane behind the ray's origin. 7808 if ((dist[0] < -EPS ) || 7809 (isSegment && (dist[0] > 1.0+EPS))) { 7810 // Ray intersects the plane behind the ray's origin 7811 // or intersect point not fall in Segment 7812 return false; 7813 } 7814 7815 // Now, one thing for sure the ray intersect the plane. 7816 // Find the intersection point. 7817 if (iPnt == null) { 7818 iPnt = new Point3d(); 7819 } 7820 iPnt.x = origin.x + direction.x * dist[0]; 7821 iPnt.y = origin.y + direction.y * dist[0]; 7822 iPnt.z = origin.z + direction.z * dist[0]; 7823 7824 // Project 3d points onto 2d plane 7825 // Find the axis so that area of projection is maximize. 7826 absNrmX = Math.abs(pNrm.x); 7827 absNrmY = Math.abs(pNrm.y); 7828 absNrmZ = Math.abs(pNrm.z); 7829 7830 // All sign of (y - y0) (x1 - x0) - (x - x0) (y1 - y0) 7831 // must agree. 7832 double sign, t, lastSign = 0; 7833 Point3d p0 = coordinates[coordinates.length-1]; 7834 Point3d p1 = coordinates[0]; 7835 7836 isIntersect = true; 7837 7838 if (absNrmX > absNrmY) { 7839 if (absNrmX < absNrmZ) { 7840 for (i=0; i < coordinates.length; i++) { 7841 p0 = coordinates[i]; 7842 p1 = (i != coordinates.length-1 ? coordinates[i+1]: coordinates[0]); 7843 sign = (iPnt.y - p0.y)*(p1.x - p0.x) - 7844 (iPnt.x - p0.x)*(p1.y - p0.y); 7845 if (isNonZero(sign)) { 7846 if (sign*lastSign < 0) { 7847 isIntersect = false; 7848 break; 7849 } 7850 lastSign = sign; 7851 } else { // point on line, check inside interval 7852 t = p1.y - p0.y; 7853 if (isNonZero(t)) { 7854 t = (iPnt.y - p0.y)/t; 7855 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7856 break; 7857 } else { 7858 t = p1.x - p0.x; 7859 if (isNonZero(t)) { 7860 t = (iPnt.x - p0.x)/t; 7861 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7862 break; 7863 } else { 7864 // Ignore degenerate line=>point happen when Quad => Triangle. 7865 // Note that by next round sign*lastSign = 0 so it will 7866 // not pass the interest test. This should only happen once in the 7867 // loop because we already check for degenerate geometry before. 7868 } 7869 } 7870 } 7871 } 7872 } else { 7873 for (i=0; i<coordinates.length; i++) { 7874 p0 = coordinates[i]; 7875 p1 = (i != coordinates.length-1 ? coordinates[i+1]: coordinates[0]); 7876 sign = (iPnt.y - p0.y)*(p1.z - p0.z) - 7877 (iPnt.z - p0.z)*(p1.y - p0.y); 7878 if (isNonZero(sign)) { 7879 if (sign*lastSign < 0) { 7880 isIntersect = false; 7881 break; 7882 } 7883 lastSign = sign; 7884 } else { // point on line, check inside interval 7885 t = p1.y - p0.y; 7886 7887 if (isNonZero(t)) { 7888 t = (iPnt.y - p0.y)/t; 7889 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7890 break; 7891 7892 } else { 7893 t = p1.z - p0.z; 7894 if (isNonZero(t)) { 7895 t = (iPnt.z - p0.z)/t; 7896 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7897 break; 7898 } else { 7899 //degenerate line=>point 7900 } 7901 } 7902 } 7903 } 7904 } 7905 } else { 7906 if (absNrmY < absNrmZ) { 7907 for (i=0; i<coordinates.length; i++) { 7908 p0 = coordinates[i]; 7909 p1 = (i != coordinates.length-1 ? coordinates[i+1]: coordinates[0]); 7910 sign = (iPnt.y - p0.y)*(p1.x - p0.x) - 7911 (iPnt.x - p0.x)*(p1.y - p0.y); 7912 if (isNonZero(sign)) { 7913 if (sign*lastSign < 0) { 7914 isIntersect = false; 7915 break; 7916 } 7917 lastSign = sign; 7918 } else { // point on line, check inside interval 7919 t = p1.y - p0.y; 7920 if (isNonZero(t)) { 7921 t = (iPnt.y - p0.y)/t; 7922 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7923 break; 7924 } else { 7925 t = p1.x - p0.x; 7926 if (isNonZero(t)) { 7927 t = (iPnt.x - p0.x)/t; 7928 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7929 break; 7930 } else { 7931 //degenerate line=>point 7932 } 7933 } 7934 } 7935 } 7936 } else { 7937 for (i=0; i<coordinates.length; i++) { 7938 p0 = coordinates[i]; 7939 p1 = (i != coordinates.length-1 ? coordinates[i+1]: coordinates[0]); 7940 sign = (iPnt.x - p0.x)*(p1.z - p0.z) - 7941 (iPnt.z - p0.z)*(p1.x - p0.x); 7942 if (isNonZero(sign)) { 7943 if (sign*lastSign < 0) { 7944 isIntersect = false; 7945 break; 7946 } 7947 lastSign = sign; 7948 } else { // point on line, check inside interval 7949 t = p1.x - p0.x; 7950 if (isNonZero(t)) { 7951 t = (iPnt.x - p0.x)/t; 7952 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7953 break; 7954 } else { 7955 t = p1.z - p0.z; 7956 if (isNonZero(t)) { 7957 t = (iPnt.z - p0.z)/t; 7958 isIntersect = ((t > -EPS) && (t < 1+EPS)); 7959 break; 7960 } else { 7961 //degenerate line=>point 7962 } 7963 } 7964 } 7965 } 7966 } 7967 } 7968 7969 if (isIntersect) { 7970 dist[0] *= direction.length(); 7971 } 7972 return isIntersect; 7973 } 7974 7975 7976 isNonZero(double v)7977 static final boolean isNonZero(double v) { 7978 return ((v > EPS) || (v < -EPS)); 7979 7980 } 7981 7982 /** 7983 * Return true if point is on the inside of halfspace test. The 7984 * halfspace is partition by the plane of triangle or quad. 7985 */ inside( Point3d coordinates[], PickPoint point, int ccw )7986 boolean inside( Point3d coordinates[], PickPoint point, int ccw ) { 7987 7988 Vector3d vec0 = new Vector3d(); // Edge vector from point 0 to point 1; 7989 Vector3d vec1 = new Vector3d(); // Edge vector from point 0 to point 2 or 3; 7990 Vector3d pNrm = new Vector3d(); 7991 double absNrmX, absNrmY, absNrmZ, pD = 0.0; 7992 Vector3d tempV3d = new Vector3d(); 7993 double pNrmDotrDir = 0.0; 7994 7995 double tempD; 7996 7997 int i, j; 7998 7999 // Compute plane normal. 8000 for(i=0; i<coordinates.length-1;) { 8001 vec0.x = coordinates[i+1].x - coordinates[i].x; 8002 vec0.y = coordinates[i+1].y - coordinates[i].y; 8003 vec0.z = coordinates[i+1].z - coordinates[i++].z; 8004 if(vec0.length() > 0.0) 8005 break; 8006 } 8007 8008 for(j=i; j<coordinates.length-1; j++) { 8009 vec1.x = coordinates[j+1].x - coordinates[j].x; 8010 vec1.y = coordinates[j+1].y - coordinates[j].y; 8011 vec1.z = coordinates[j+1].z - coordinates[j].z; 8012 if(vec1.length() > 0.0) 8013 break; 8014 } 8015 8016 if(j == (coordinates.length-1)) { 8017 // System.err.println("(1) Degenerate polygon."); 8018 return false; // Degenerate polygon. 8019 } 8020 8021 /* 8022 System.err.println("Ray orgin : " + ray.origin + " dir " + ray.direction); 8023 System.err.println("Triangle/Quad :"); 8024 for(i=0; i<coordinates.length; i++) 8025 System.err.println("P" + i + " " + coordinates[i]); 8026 */ 8027 8028 if( ccw == 0x1) 8029 pNrm.cross(vec0,vec1); 8030 else 8031 pNrm.cross(vec1,vec0); 8032 8033 if(pNrm.length() == 0.0) { 8034 // System.err.println("(2) Degenerate polygon."); 8035 return false; // Degenerate polygon. 8036 } 8037 // Compute plane D. 8038 tempV3d.set((Tuple3d) coordinates[0]); 8039 pD = pNrm.dot(tempV3d); 8040 tempV3d.set((Tuple3d) point.location); 8041 8042 return ((pD - pNrm.dot(tempV3d)) <= 0); 8043 } 8044 intersectPntAndPnt( Point3d pnt1, Point3d pnt2 )8045 boolean intersectPntAndPnt( Point3d pnt1, Point3d pnt2 ) { 8046 return ((pnt1.x == pnt2.x) && 8047 (pnt1.y == pnt2.y) && 8048 (pnt1.z == pnt2.z)); 8049 } 8050 intersectPntAndRay(Point3d pnt, Point3d ori, Vector3d dir, double dist[])8051 boolean intersectPntAndRay(Point3d pnt, Point3d ori, Vector3d dir, 8052 double dist[]) { 8053 int flag = 0; 8054 double temp; 8055 8056 if(dir.x != 0.0) { 8057 flag = 0; 8058 dist[0] = (pnt.x - ori.x)/dir.x; 8059 } 8060 else if(dir.y != 0.0) { 8061 if(pnt.x != ori.x) 8062 return false; 8063 flag = 1; 8064 dist[0] = (pnt.y - ori.y)/dir.y; 8065 } 8066 else if(dir.z != 0.0) { 8067 if((pnt.x != ori.x)||(pnt.y != ori.y)) 8068 return false; 8069 flag = 2; 8070 dist[0] = (pnt.z - ori.z)/dir.z; 8071 8072 } 8073 else 8074 return false; 8075 8076 if(dist[0] < 0.0) 8077 return false; 8078 8079 if(flag == 0) { 8080 temp = ori.y + dist[0] * dir.y; 8081 if((pnt.y < (temp - EPS)) || (pnt.y > (temp + EPS))) 8082 return false; 8083 } 8084 8085 if(flag < 2) { 8086 temp = ori.z + dist[0] * dir.z; 8087 if((pnt.z < (temp - EPS)) || (pnt.z > (temp + EPS))) 8088 return false; 8089 } 8090 8091 return true; 8092 8093 } 8094 intersectLineAndRay(Point3d start, Point3d end, Point3d ori, Vector3d dir, double dist[], Point3d iPnt)8095 boolean intersectLineAndRay(Point3d start, Point3d end, 8096 Point3d ori, Vector3d dir, double dist[], 8097 Point3d iPnt) { 8098 8099 double m00, m01, m10, m11; 8100 double mInv00, mInv01, mInv10, mInv11; 8101 double dmt, t, s, tmp1, tmp2; 8102 Vector3d lDir; 8103 8104 // System.err.println("GeometryArrayRetained : intersectLineAndRay"); 8105 // System.err.println("start " + start + " end " + end ); 8106 // System.err.println("ori " + ori + " dir " + dir); 8107 8108 lDir = new Vector3d(); 8109 lDir.x = (end.x - start.x); 8110 lDir.y = (end.y - start.y); 8111 lDir.z = (end.z - start.z); 8112 8113 m00 = lDir.x; 8114 m01 = -dir.x; 8115 m10 = lDir.y; 8116 m11 = -dir.y; 8117 8118 // Get the determinant. 8119 dmt = (m00 * m11) - (m10 * m01); 8120 8121 if (dmt==0.0) { // No solution, check degenerate line 8122 boolean isIntersect = false; 8123 if ((lDir.x == 0) && (lDir.y == 0) && (lDir.z == 0)) { 8124 isIntersect = intersectPntAndRay(start, ori, dir, dist); 8125 if (isIntersect && (iPnt != null)) { 8126 iPnt.set(start); 8127 } 8128 } 8129 return isIntersect; 8130 } 8131 // Find the inverse. 8132 tmp1 = 1/dmt; 8133 8134 mInv00 = tmp1 * m11; 8135 mInv01 = tmp1 * (-m01); 8136 mInv10 = tmp1 * (-m10); 8137 mInv11 = tmp1 * m00; 8138 8139 tmp1 = ori.x - start.x; 8140 tmp2 = ori.y - start.y; 8141 8142 t = mInv00 * tmp1 + mInv01 * tmp2; 8143 s = mInv10 * tmp1 + mInv11 * tmp2; 8144 8145 if(s<0.0) { // Before the origin of ray. 8146 // System.err.println("Before the origin of ray " + s); 8147 return false; 8148 } 8149 if((t<0)||(t>1.0)) {// Before or after the end points of line. 8150 // System.err.println("Before or after the end points of line. " + t); 8151 return false; 8152 } 8153 8154 tmp1 = ori.z + s * dir.z; 8155 tmp2 = start.z + t * lDir.z; 8156 8157 if((tmp1 < (tmp2 - EPS)) || (tmp1 > (tmp2 + EPS))) { 8158 // System.err.println("No intersection : tmp1 " + tmp1 + " tmp2 " + tmp2); 8159 return false; 8160 } 8161 8162 dist[0] = s; 8163 8164 if (iPnt != null) { 8165 // compute point of intersection. 8166 iPnt.x = ori.x + dir.x * dist[0]; 8167 iPnt.y = ori.y + dir.y * dist[0]; 8168 iPnt.z = ori.z + dir.z * dist[0]; 8169 } 8170 8171 // System.err.println("Intersected : tmp1 " + tmp1 + " tmp2 " + tmp2); 8172 return true; 8173 } 8174 8175 /** 8176 Return true if triangle or quad intersects with cylinder. The 8177 distance is stored in dist. 8178 */ intersectCylinder(Point3d coordinates[], PickCylinder cyl, double dist[], Point3d iPnt)8179 boolean intersectCylinder(Point3d coordinates[], PickCylinder cyl, 8180 double dist[], Point3d iPnt) { 8181 8182 Point3d origin = new Point3d(); 8183 Point3d end = new Point3d(); 8184 Vector3d direction = new Vector3d(); 8185 Point3d iPnt1 = new Point3d(); 8186 Vector3d originToIpnt = new Vector3d(); 8187 8188 if (iPnt == null) { 8189 iPnt = new Point3d(); 8190 } 8191 8192 // Get cylinder information 8193 cyl.getOrigin (origin); 8194 cyl.getDirection (direction); 8195 double radius = cyl.getRadius (); 8196 8197 if (cyl instanceof PickCylinderSegment) { 8198 ((PickCylinderSegment)cyl).getEnd (end); 8199 } 8200 8201 // If the ray intersects, we're good (do not do this if we only have 8202 // a segment 8203 if (coordinates.length > 2) { 8204 if (cyl instanceof PickCylinderRay) { 8205 if (intersectRay(coordinates, 8206 new PickRay(origin, direction), 8207 dist, iPnt)) { 8208 return true; 8209 } 8210 } 8211 else { 8212 if (intersectSegment(coordinates, origin, end, dist, iPnt)) { 8213 return true; 8214 } 8215 } 8216 } 8217 8218 // Ray doesn't intersect, check distance to edges 8219 double sqDistToEdge; 8220 int j; 8221 for (int i=0; i<coordinates.length;i++) { 8222 j = (i < coordinates.length-1 ? i+1: 0); 8223 if (cyl instanceof PickCylinderSegment) { 8224 sqDistToEdge = 8225 Distance.segmentToSegment(origin, end, 8226 coordinates[i], coordinates[j], 8227 iPnt1, iPnt, null); 8228 } 8229 else { 8230 sqDistToEdge = 8231 Distance.rayToSegment(origin, direction, 8232 coordinates[i], coordinates[j], 8233 iPnt1, iPnt, null); 8234 } 8235 if (sqDistToEdge <= radius*radius) { 8236 originToIpnt.sub (iPnt1, origin); 8237 dist[0] = originToIpnt.length(); 8238 return true; 8239 } 8240 } 8241 return false; 8242 } 8243 8244 /** 8245 Return true if triangle or quad intersects with cone. The 8246 distance is stored in dist. 8247 */ intersectCone(Point3d coordinates[], PickCone cone, double[] dist, Point3d iPnt)8248 boolean intersectCone(Point3d coordinates[], PickCone cone, 8249 double[] dist, Point3d iPnt) { 8250 8251 Point3d origin = new Point3d(); 8252 Point3d end = new Point3d(); 8253 Vector3d direction = new Vector3d(); 8254 Vector3d originToIpnt = new Vector3d(); 8255 double distance; 8256 8257 Point3d iPnt1 = new Point3d(); 8258 Vector3d vector = new Vector3d(); 8259 8260 if (iPnt == null) { 8261 iPnt = new Point3d(); 8262 } 8263 // Get cone information 8264 cone.getOrigin (origin); 8265 cone.getDirection (direction); 8266 double radius; 8267 8268 if (cone instanceof PickConeSegment) { 8269 ((PickConeSegment)cone).getEnd (end); 8270 } 8271 8272 // If the ray intersects, we're good (do not do this if we only have 8273 // a segment 8274 if (coordinates.length > 2) { 8275 if (cone instanceof PickConeRay) { 8276 if (intersectRay(coordinates, 8277 new PickRay (origin, direction), 8278 dist, iPnt)) { 8279 return true; 8280 } 8281 } 8282 else { 8283 if (intersectSegment(coordinates, origin, end, dist, iPnt)) { 8284 return true; 8285 } 8286 } 8287 } 8288 8289 // Ray doesn't intersect, check distance to edges 8290 double sqDistToEdge; 8291 int j = 0; 8292 for (int i=0; i<coordinates.length;i++) { 8293 j = (i < coordinates.length-1 ? i+1: 0); 8294 if (cone instanceof PickConeSegment) { 8295 sqDistToEdge = 8296 Distance.segmentToSegment (origin, end, 8297 coordinates[i], coordinates[j], 8298 iPnt1, iPnt, null); 8299 } 8300 else { 8301 sqDistToEdge = 8302 Distance.rayToSegment (origin, direction, 8303 coordinates[i], coordinates[j], 8304 iPnt1, iPnt, null); 8305 } 8306 originToIpnt.sub(iPnt1, origin); 8307 distance = originToIpnt.length(); 8308 radius = Math.tan (cone.getSpreadAngle()) * distance; 8309 if (sqDistToEdge <= radius*radius) { 8310 // System.err.println ("intersectCone: edge "+i+" intersected"); 8311 dist[0] = distance; 8312 return true; 8313 } 8314 } 8315 return false; 8316 } 8317 8318 8319 /** 8320 Return true if point intersects with cylinder and the distance is 8321 stored in dist. 8322 */ intersectCylinder(Point3d pt, PickCylinder cyl, double[] dist)8323 boolean intersectCylinder(Point3d pt, PickCylinder cyl, 8324 double[] dist) { 8325 8326 Point3d origin = new Point3d(); 8327 Point3d end = new Point3d(); 8328 Vector3d direction = new Vector3d(); 8329 Point3d iPnt = new Point3d(); 8330 Vector3d originToIpnt = new Vector3d(); 8331 8332 // Get cylinder information 8333 cyl.getOrigin (origin); 8334 cyl.getDirection (direction); 8335 double radius = cyl.getRadius (); 8336 double sqDist; 8337 8338 if (cyl instanceof PickCylinderSegment) { 8339 ((PickCylinderSegment)cyl).getEnd (end); 8340 sqDist = Distance.pointToSegment(pt, origin, end, iPnt, null); 8341 } 8342 else { 8343 sqDist = Distance.pointToRay(pt, origin, direction, iPnt, null); 8344 } 8345 if (sqDist <= radius*radius) { 8346 originToIpnt.sub (iPnt, origin); 8347 dist[0] = originToIpnt.length(); 8348 return true; 8349 } 8350 return false; 8351 } 8352 8353 /** 8354 Return true if point intersects with cone and the 8355 distance is stored in pi. 8356 */ intersectCone(Point3d pt, PickCone cone, double[] dist)8357 boolean intersectCone(Point3d pt, PickCone cone, double[] dist) 8358 { 8359 Point3d origin = new Point3d(); 8360 Point3d end = new Point3d(); 8361 Vector3d direction = new Vector3d(); 8362 Point3d iPnt = new Point3d(); 8363 Vector3d originToIpnt = new Vector3d(); 8364 8365 // Get cone information 8366 cone.getOrigin (origin); 8367 cone.getDirection (direction); 8368 double radius; 8369 double distance; 8370 double sqDist; 8371 8372 if (iPnt == null) { 8373 iPnt = new Point3d(); 8374 } 8375 8376 if (cone instanceof PickConeSegment) { 8377 ((PickConeSegment)cone).getEnd (end); 8378 sqDist = Distance.pointToSegment (pt, origin, end, iPnt, null); 8379 } 8380 else { 8381 sqDist = Distance.pointToRay (pt, origin, direction, iPnt, null); 8382 } 8383 originToIpnt.sub(iPnt, origin); 8384 distance = originToIpnt.length(); 8385 radius = Math.tan (cone.getSpreadAngle()) * distance; 8386 if (sqDist <= radius*radius) { 8387 dist[0] = distance; 8388 return true; 8389 } 8390 return false; 8391 } 8392 8393 setCoordRefBuffer(J3DBuffer coords)8394 void setCoordRefBuffer(J3DBuffer coords) { 8395 if (coords != null) { 8396 switch (coords.getBufferType()) { 8397 case J3DBuffer.TYPE_FLOAT: 8398 assert ((FloatBufferWrapper)coords.getBufferImpl()).isDirect(); 8399 break; 8400 case J3DBuffer.TYPE_DOUBLE: 8401 assert ((DoubleBufferWrapper)coords.getBufferImpl()).isDirect(); 8402 break; 8403 case J3DBuffer.TYPE_NULL: 8404 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray115")); 8405 8406 default: 8407 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116")); 8408 } 8409 8410 if (this instanceof IndexedGeometryArrayRetained) { 8411 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8412 if (3 * idx.maxCoordIndex >= coords.getBufferImpl().limit()) { 8413 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 8414 } 8415 } else if (coords.getBufferImpl().limit() < (3*(initialCoordIndex+validVertexCount))) { 8416 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 8417 } 8418 } 8419 8420 // lock the geometry and start to do real work 8421 boolean isLive = source!=null && source.isLive(); 8422 if(isLive){ 8423 geomLock.getLock(); 8424 } 8425 dirtyFlag |= COORDINATE_CHANGED; 8426 coordRefBuffer = coords; 8427 if(coords == null) { 8428 floatBufferRefCoords = null; 8429 doubleBufferRefCoords = null; 8430 // XXXX: if not mix java array with nio buffer 8431 // vertexType can be used as vertexTypeBuffer 8432 vertexType &= ~PD; 8433 vertexType &= ~PF; 8434 }else { 8435 switch (coords.getBufferType()) { 8436 case J3DBuffer.TYPE_FLOAT: 8437 floatBufferRefCoords = 8438 (FloatBufferWrapper)coords.getBufferImpl(); 8439 doubleBufferRefCoords = null; 8440 vertexType |= PF; 8441 vertexType &= ~PD; 8442 break; 8443 case J3DBuffer.TYPE_DOUBLE: 8444 floatBufferRefCoords = null; 8445 doubleBufferRefCoords = 8446 (DoubleBufferWrapper)coords.getBufferImpl(); 8447 vertexType |= PD; 8448 vertexType &= ~PF; 8449 break; 8450 default: 8451 break; 8452 } 8453 } 8454 8455 // need not call setupMirrorVertexPointer() since 8456 // we are not going to set mirror in NIO buffer case 8457 // XXXX: if we need to mix java array with buffer, 8458 // we may need to consider setupMirrorVertexPointer() 8459 8460 if(isLive) { 8461 geomLock.unLock(); 8462 } 8463 if (!inUpdater && source != null) { 8464 if (isLive) { 8465 processCoordsChanged((coords == null)); 8466 sendDataChangedMessage(true); 8467 } else { 8468 boundsDirty = true; 8469 } 8470 } 8471 8472 } 8473 8474 getCoordRefBuffer()8475 J3DBuffer getCoordRefBuffer() { 8476 return coordRefBuffer; 8477 } 8478 8479 setCoordRefFloat(float[] coords)8480 void setCoordRefFloat(float[] coords) { 8481 8482 // If non-null coordinate and vertType is either defined 8483 // to be something other than PF, then issue an error 8484 if (coords != null) { 8485 if ((vertexType & VERTEX_DEFINED) != 0 && 8486 (vertexType & VERTEX_DEFINED) != PF) { 8487 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8488 } 8489 8490 8491 if (this instanceof IndexedGeometryArrayRetained) { 8492 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8493 8494 if (3 * idx.maxCoordIndex >= coords.length) { 8495 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 8496 } 8497 } else if (coords.length < 3 * (initialCoordIndex+validVertexCount)) { 8498 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 8499 } 8500 } 8501 boolean isLive = source!=null && source.isLive(); 8502 if(isLive){ 8503 geomLock.getLock(); 8504 } 8505 dirtyFlag |= COORDINATE_CHANGED; 8506 8507 floatRefCoords = coords; 8508 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8509 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8510 if (coords == null) 8511 vertexType &= ~PF; 8512 else 8513 vertexType |= PF; 8514 } 8515 else { 8516 setupMirrorVertexPointer(PF); 8517 } 8518 8519 if(isLive) { 8520 geomLock.unLock(); 8521 } 8522 if (!inUpdater && source != null) { 8523 if (isLive) { 8524 processCoordsChanged(coords == null); 8525 sendDataChangedMessage(true); 8526 } else { 8527 boundsDirty = true; 8528 } 8529 } 8530 } 8531 8532 getCoordRefFloat()8533 float[] getCoordRefFloat() { 8534 return floatRefCoords; 8535 } 8536 8537 setCoordRefDouble(double[] coords)8538 void setCoordRefDouble(double[] coords) { 8539 8540 if (coords != null) { 8541 if ((vertexType & VERTEX_DEFINED) != 0 && 8542 (vertexType & VERTEX_DEFINED) != PD) { 8543 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8544 } 8545 8546 if (this instanceof IndexedGeometryArrayRetained) { 8547 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8548 if (3 * idx.maxCoordIndex >= coords.length) { 8549 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 8550 } 8551 } else if (coords.length < 3 * (initialCoordIndex+validVertexCount)) { 8552 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 8553 } 8554 } 8555 boolean isLive = source!=null && source.isLive(); 8556 if(isLive){ 8557 geomLock.getLock(); 8558 } 8559 dirtyFlag |= COORDINATE_CHANGED; 8560 doubleRefCoords = coords; 8561 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8562 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8563 if (coords == null) 8564 vertexType &= ~PD; 8565 else 8566 vertexType |= PD; 8567 } 8568 else { 8569 setupMirrorVertexPointer(PD); 8570 } 8571 if(isLive) { 8572 geomLock.unLock(); 8573 } 8574 if (!inUpdater && source != null) { 8575 if (isLive) { 8576 processCoordsChanged(coords == null); 8577 sendDataChangedMessage(true); 8578 } else { 8579 boundsDirty = true; 8580 } 8581 } 8582 } 8583 getCoordRefDouble()8584 double[] getCoordRefDouble() { 8585 return doubleRefCoords; 8586 } 8587 setCoordRef3f(Point3f[] coords)8588 void setCoordRef3f(Point3f[] coords) { 8589 8590 if (coords != null) { 8591 if ((vertexType & VERTEX_DEFINED) != 0 && 8592 (vertexType & VERTEX_DEFINED) != P3F) { 8593 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8594 } 8595 8596 if (this instanceof IndexedGeometryArrayRetained) { 8597 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8598 8599 if (idx.maxCoordIndex >= coords.length) { 8600 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 8601 } 8602 } else if (coords.length < (initialCoordIndex+validVertexCount) ) { 8603 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 8604 } 8605 } 8606 boolean isLive = source!=null && source.isLive(); 8607 if(isLive){ 8608 geomLock.getLock(); 8609 } 8610 dirtyFlag |= COORDINATE_CHANGED; 8611 p3fRefCoords = coords; 8612 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8613 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8614 if (coords == null) 8615 vertexType &= ~P3F; 8616 else 8617 vertexType |= P3F; 8618 } 8619 else { 8620 setupMirrorVertexPointer(P3F); 8621 } 8622 if(isLive) { 8623 geomLock.unLock(); 8624 } 8625 if (!inUpdater && source != null) { 8626 if (isLive) { 8627 processCoordsChanged(coords == null); 8628 sendDataChangedMessage(true); 8629 } else { 8630 boundsDirty = true; 8631 } 8632 } 8633 } 8634 getCoordRef3f()8635 Point3f[] getCoordRef3f() { 8636 return p3fRefCoords; 8637 8638 } 8639 setCoordRef3d(Point3d[] coords)8640 void setCoordRef3d(Point3d[] coords) { 8641 8642 if (coords != null) { 8643 if ((vertexType & VERTEX_DEFINED) != 0 && 8644 (vertexType & VERTEX_DEFINED) != P3D) { 8645 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8646 } 8647 8648 if (this instanceof IndexedGeometryArrayRetained) { 8649 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8650 8651 if (idx.maxCoordIndex >= coords.length) { 8652 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 8653 } 8654 } else if (coords.length < (initialCoordIndex+validVertexCount) ) { 8655 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 8656 } 8657 } 8658 boolean isLive = source!=null && source.isLive(); 8659 if(isLive){ 8660 geomLock.getLock(); 8661 } 8662 dirtyFlag |= COORDINATE_CHANGED; 8663 p3dRefCoords = coords; 8664 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8665 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8666 if (coords == null) 8667 vertexType &= ~P3D; 8668 else 8669 vertexType |= P3D; 8670 } else { 8671 setupMirrorVertexPointer(P3D); 8672 } 8673 if(isLive) { 8674 geomLock.unLock(); 8675 } 8676 if (!inUpdater && source != null) { 8677 if (isLive) { 8678 processCoordsChanged(coords == null); 8679 sendDataChangedMessage(true); 8680 } else { 8681 boundsDirty = true; 8682 } 8683 } 8684 } 8685 getCoordRef3d()8686 Point3d[] getCoordRef3d() { 8687 return p3dRefCoords; 8688 } 8689 setColorRefFloat(float[] colors)8690 void setColorRefFloat(float[] colors) { 8691 8692 if (colors != null) { 8693 if ((vertexType & COLOR_DEFINED) != 0 && 8694 (vertexType & COLOR_DEFINED) != CF) { 8695 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8696 } 8697 8698 if ((vertexFormat & GeometryArray.COLOR) == 0) { 8699 throw new IllegalStateException(J3dI18N.getString("GeometryArray123")); 8700 } 8701 8702 if (this instanceof IndexedGeometryArrayRetained) { 8703 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8704 8705 if (getColorStride() * idx.maxColorIndex >= colors.length) { 8706 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 8707 } 8708 } else if (colors.length < getColorStride() * (initialColorIndex+ validVertexCount) ) { 8709 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 8710 } 8711 } 8712 8713 boolean isLive = source!=null && source.isLive(); 8714 if(isLive){ 8715 geomLock.getLock(); 8716 } 8717 dirtyFlag |= COLOR_CHANGED; 8718 colorChanged = 0xffff; 8719 floatRefColors = colors; 8720 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8721 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8722 if (colors == null) 8723 vertexType &= ~CF; 8724 else 8725 vertexType |= CF; 8726 } 8727 else { 8728 setupMirrorColorPointer(CF, false); 8729 } 8730 8731 if(isLive) { 8732 geomLock.unLock(); 8733 } 8734 if (!inUpdater && isLive) { 8735 sendDataChangedMessage(false); 8736 } 8737 8738 } 8739 getColorRefFloat()8740 float[] getColorRefFloat() { 8741 return floatRefColors; 8742 } 8743 8744 8745 // set the color with nio buffer setColorRefBuffer(J3DBuffer colors)8746 void setColorRefBuffer(J3DBuffer colors) { 8747 if (colors != null) { 8748 switch(colors.getBufferType()) { 8749 case J3DBuffer.TYPE_FLOAT: 8750 assert ((FloatBufferWrapper)colors.getBufferImpl()).isDirect(); 8751 break; 8752 case J3DBuffer.TYPE_BYTE: 8753 assert ((ByteBufferWrapper)colors.getBufferImpl()).isDirect(); 8754 break; 8755 case J3DBuffer.TYPE_NULL: 8756 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray115")); 8757 8758 default: 8759 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116")); 8760 } 8761 8762 if ((vertexFormat & GeometryArray.COLOR) == 0) { 8763 throw new IllegalStateException(J3dI18N.getString("GeometryArray123")); 8764 } 8765 8766 if (this instanceof IndexedGeometryArrayRetained) { 8767 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8768 8769 if (getColorStride() * idx.maxColorIndex >= colors.getBufferImpl().limit()) { 8770 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 8771 } 8772 } else if (colors.getBufferImpl().limit() < 8773 getColorStride() * (initialColorIndex+validVertexCount)) { 8774 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 8775 } 8776 } 8777 8778 boolean isLive = source!=null && source.isLive(); 8779 if(isLive){ 8780 geomLock.getLock(); 8781 } 8782 dirtyFlag |= COLOR_CHANGED; 8783 colorChanged = 0xffff; 8784 colorRefBuffer = colors; 8785 if(colors == null) { 8786 floatBufferRefColors = null; 8787 byteBufferRefColors = null; 8788 } else { 8789 switch (colors.getBufferType()) { 8790 case J3DBuffer.TYPE_FLOAT: 8791 floatBufferRefColors = (FloatBufferWrapper)colors.getBufferImpl(); 8792 byteBufferRefColors = null; 8793 break; 8794 8795 case J3DBuffer.TYPE_BYTE: 8796 byteBufferRefColors = (ByteBufferWrapper)colors.getBufferImpl(); 8797 floatBufferRefColors = null; 8798 break; 8799 default: 8800 break; 8801 } 8802 } 8803 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8804 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8805 if(colors == null) { 8806 vertexType &= ~CF; 8807 vertexType &= ~CUB; 8808 } else { 8809 switch (colors.getBufferType()) { 8810 case J3DBuffer.TYPE_FLOAT: 8811 vertexType |= CF; 8812 vertexType &= ~CUB; 8813 break; 8814 8815 case J3DBuffer.TYPE_BYTE: 8816 vertexType |= CUB; 8817 vertexType &= ~CF; 8818 break; 8819 default: 8820 break; 8821 } 8822 } 8823 } 8824 else { 8825 setupMirrorColorPointer(CF|CUB, false); 8826 } 8827 8828 if(isLive) { 8829 geomLock.unLock(); 8830 } 8831 8832 if (!inUpdater && isLive) { 8833 sendDataChangedMessage(false); 8834 } 8835 } 8836 8837 // return the color data in nio buffer format getColorRefBuffer()8838 J3DBuffer getColorRefBuffer() { 8839 return colorRefBuffer; 8840 } 8841 setColorRefByte(byte[] colors)8842 void setColorRefByte(byte[] colors) { 8843 8844 if (colors != null) { 8845 if ((vertexType & COLOR_DEFINED) != 0 && 8846 (vertexType & COLOR_DEFINED) != CUB) { 8847 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8848 } 8849 8850 if ((vertexFormat & GeometryArray.COLOR) == 0) { 8851 throw new IllegalStateException(J3dI18N.getString("GeometryArray123")); 8852 } 8853 8854 if (this instanceof IndexedGeometryArrayRetained) { 8855 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8856 8857 if (getColorStride() * idx.maxColorIndex >= colors.length) { 8858 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 8859 } 8860 } else if (colors.length < getColorStride() * (initialColorIndex + validVertexCount)) { 8861 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 8862 } 8863 } 8864 boolean isLive = source!=null && source.isLive(); 8865 if(isLive){ 8866 geomLock.getLock(); 8867 } 8868 dirtyFlag |= COLOR_CHANGED; 8869 colorChanged = 0xffff; 8870 byteRefColors = colors; 8871 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8872 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8873 if (colors == null) 8874 vertexType &= ~CUB; 8875 else 8876 vertexType |= CUB; 8877 } 8878 else { 8879 setupMirrorColorPointer(CUB, false); 8880 } 8881 if(isLive){ 8882 geomLock.unLock(); 8883 } 8884 8885 if (!inUpdater && isLive) { 8886 sendDataChangedMessage(false); 8887 } 8888 8889 } 8890 getColorRefByte()8891 byte[] getColorRefByte() { 8892 return byteRefColors; 8893 } 8894 setColorRef3f(Color3f[] colors)8895 void setColorRef3f(Color3f[] colors) { 8896 8897 if (colors != null) { 8898 if ((vertexType & COLOR_DEFINED) != 0 && 8899 (vertexType & COLOR_DEFINED) != C3F) { 8900 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8901 } 8902 8903 if ((vertexFormat & GeometryArray.COLOR_3) == 0) { 8904 throw new IllegalStateException(J3dI18N.getString("GeometryArray92")); 8905 } 8906 8907 if (this instanceof IndexedGeometryArrayRetained) { 8908 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8909 if (idx.maxColorIndex >= colors.length) { 8910 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 8911 } 8912 } else if (colors.length < (initialColorIndex + validVertexCount) ) { 8913 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 8914 } 8915 } 8916 8917 boolean isLive = source!=null && source.isLive(); 8918 if(isLive){ 8919 geomLock.getLock(); 8920 } 8921 dirtyFlag |= COLOR_CHANGED; 8922 colorChanged = 0xffff; 8923 c3fRefColors = colors; 8924 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8925 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8926 if (colors == null) 8927 vertexType &= ~C3F; 8928 else 8929 vertexType |= C3F; 8930 } 8931 else { 8932 setupMirrorColorPointer(C3F, false); 8933 } 8934 8935 if(isLive) { 8936 geomLock.unLock(); 8937 } 8938 8939 if (!inUpdater && isLive) { 8940 sendDataChangedMessage(false); 8941 } 8942 8943 } 8944 getColorRef3f()8945 Color3f[] getColorRef3f() { 8946 return c3fRefColors; 8947 } 8948 8949 setColorRef4f(Color4f[] colors)8950 void setColorRef4f(Color4f[] colors) { 8951 8952 if (colors != null) { 8953 if ((vertexType & COLOR_DEFINED) != 0 && 8954 (vertexType & COLOR_DEFINED) != C4F) { 8955 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 8956 } 8957 if ((vertexFormat & GeometryArray.COLOR_4) == 0) { 8958 throw new IllegalStateException(J3dI18N.getString("GeometryArray93")); 8959 } 8960 8961 if (this instanceof IndexedGeometryArrayRetained) { 8962 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 8963 if (idx.maxColorIndex >= colors.length) { 8964 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 8965 } 8966 } else if (colors.length < (initialColorIndex + validVertexCount) ) { 8967 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 8968 } 8969 } 8970 boolean isLive = source!=null && source.isLive(); 8971 if(isLive){ 8972 geomLock.getLock(); 8973 } 8974 dirtyFlag |= COLOR_CHANGED; 8975 colorChanged = 0xffff; 8976 c4fRefColors = colors; 8977 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 8978 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 8979 if (colors == null) 8980 vertexType &= ~C4F; 8981 else 8982 vertexType |= C4F; 8983 } 8984 else { 8985 setupMirrorColorPointer(C4F, false); 8986 } 8987 if(isLive) { 8988 geomLock.unLock(); 8989 } 8990 8991 if (!inUpdater && isLive) { 8992 sendDataChangedMessage(false); 8993 } 8994 } 8995 getColorRef4f()8996 Color4f[] getColorRef4f() { 8997 return c4fRefColors; 8998 } 8999 9000 setColorRef3b(Color3b[] colors)9001 void setColorRef3b(Color3b[] colors) { 9002 9003 if (colors != null) { 9004 9005 if ((vertexType & COLOR_DEFINED) != 0 && 9006 (vertexType & COLOR_DEFINED) != C3UB) { 9007 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 9008 } 9009 9010 if ((vertexFormat & GeometryArray.COLOR_3) == 0) { 9011 throw new IllegalStateException(J3dI18N.getString("GeometryArray92")); 9012 } 9013 9014 if (this instanceof IndexedGeometryArrayRetained) { 9015 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9016 9017 if (idx.maxColorIndex >= colors.length) { 9018 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 9019 } 9020 } else if (colors.length < (initialColorIndex + validVertexCount)) { 9021 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9022 } 9023 } 9024 9025 boolean isLive = source!=null && source.isLive(); 9026 if(isLive){ 9027 geomLock.getLock(); 9028 } 9029 dirtyFlag |= COLOR_CHANGED; 9030 colorChanged = 0xffff; 9031 c3bRefColors = colors; 9032 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9033 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9034 if (colors == null) 9035 vertexType &= ~C3UB; 9036 else 9037 vertexType |= C3UB; 9038 } 9039 else { 9040 setupMirrorColorPointer(C3UB, false); 9041 } 9042 9043 if(isLive) { 9044 geomLock.unLock(); 9045 } 9046 9047 if (!inUpdater && isLive) { 9048 sendDataChangedMessage(false); 9049 } 9050 } 9051 9052 getColorRef3b()9053 Color3b[] getColorRef3b() { 9054 return c3bRefColors; 9055 } 9056 setColorRef4b(Color4b[] colors)9057 void setColorRef4b(Color4b[] colors) { 9058 9059 if (colors != null) { 9060 if ((vertexType & COLOR_DEFINED) != 0 && 9061 (vertexType & COLOR_DEFINED) != C4UB) { 9062 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 9063 } 9064 9065 if ((vertexFormat & GeometryArray.COLOR_4) == 0) { 9066 throw new IllegalStateException(J3dI18N.getString("GeometryArray93")); 9067 } 9068 9069 if (this instanceof IndexedGeometryArrayRetained) { 9070 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained) this; 9071 9072 if (idx.maxColorIndex >= colors.length) { 9073 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 9074 } 9075 } else if (colors.length < (initialColorIndex + validVertexCount) ) { 9076 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9077 } 9078 } 9079 boolean isLive = source!=null && source.isLive(); 9080 if(isLive){ 9081 geomLock.getLock(); 9082 } 9083 dirtyFlag |= COLOR_CHANGED; 9084 colorChanged = 0xffff; 9085 c4bRefColors = colors; 9086 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9087 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9088 if (colors == null) 9089 vertexType &= ~C4UB; 9090 else 9091 vertexType |= C4UB; 9092 } 9093 else { 9094 setupMirrorColorPointer(C4UB, false); 9095 } 9096 9097 if(isLive) { 9098 geomLock.unLock(); 9099 } 9100 if (!inUpdater && isLive) { 9101 sendDataChangedMessage(false); 9102 } 9103 } 9104 9105 getColorRef4b()9106 Color4b[] getColorRef4b() { 9107 return c4bRefColors; 9108 } 9109 setNormalRefFloat(float[] normals)9110 void setNormalRefFloat(float[] normals) { 9111 9112 if (normals != null) { 9113 if ((vertexType & NORMAL_DEFINED) != 0 && 9114 (vertexType & NORMAL_DEFINED) != NF) { 9115 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 9116 } 9117 9118 if ((vertexFormat & GeometryArray.NORMALS) == 0) { 9119 throw new IllegalStateException(J3dI18N.getString("GeometryArray122")); 9120 } 9121 9122 if (this instanceof IndexedGeometryArrayRetained) { 9123 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9124 9125 if (idx.maxNormalIndex*3 >= normals.length) { 9126 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); 9127 } 9128 } else if (normals.length < 3 * (initialNormalIndex + validVertexCount )) { 9129 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 9130 } 9131 } 9132 boolean isLive = source!=null && source.isLive(); 9133 if(isLive){ 9134 geomLock.getLock(); 9135 } 9136 dirtyFlag |= NORMAL_CHANGED; 9137 floatRefNormals = normals; 9138 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9139 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9140 if (normals == null) 9141 vertexType &= ~NF; 9142 else 9143 vertexType |= NF; 9144 } 9145 else { 9146 setupMirrorNormalPointer(NF); 9147 } 9148 if(isLive) { 9149 geomLock.unLock(); 9150 } 9151 if (!inUpdater && isLive) { 9152 sendDataChangedMessage(false); 9153 } 9154 9155 } 9156 getNormalRefFloat()9157 float[] getNormalRefFloat() { 9158 return floatRefNormals; 9159 } 9160 9161 // setup the normal with nio buffer setNormalRefBuffer(J3DBuffer normals)9162 void setNormalRefBuffer(J3DBuffer normals) { 9163 9164 FloatBufferWrapper bufferImpl = null; 9165 9166 if (normals != null) { 9167 if(normals.getBufferType() != J3DBuffer.TYPE_FLOAT) 9168 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116")); 9169 9170 bufferImpl = (FloatBufferWrapper)normals.getBufferImpl(); 9171 9172 assert bufferImpl.isDirect(); 9173 9174 if ((vertexFormat & GeometryArray.NORMALS) == 0) { 9175 throw new IllegalStateException(J3dI18N.getString("GeometryArray122")); 9176 } 9177 9178 if (this instanceof IndexedGeometryArrayRetained) { 9179 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9180 if (idx.maxNormalIndex * 3 >= 9181 ((FloatBufferWrapper)normals.getBufferImpl()).limit()) { 9182 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); 9183 } 9184 } else if (bufferImpl.limit() < 3 * (initialNormalIndex + validVertexCount )) { 9185 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 9186 } 9187 } 9188 boolean isLive = source!=null && source.isLive(); 9189 if(isLive){ 9190 geomLock.getLock(); 9191 } 9192 dirtyFlag |= NORMAL_CHANGED; 9193 normalRefBuffer = normals; 9194 9195 if (normals == null) { 9196 vertexType &= ~NF; 9197 floatBufferRefNormals = null; 9198 } 9199 else { 9200 vertexType |= NF; 9201 floatBufferRefNormals = bufferImpl; 9202 } 9203 if(isLive) { 9204 geomLock.unLock(); 9205 } 9206 if (!inUpdater && isLive) { 9207 sendDataChangedMessage(false); 9208 } 9209 } 9210 getNormalRefBuffer()9211 J3DBuffer getNormalRefBuffer() { 9212 return normalRefBuffer; 9213 } 9214 setNormalRef3f(Vector3f[] normals)9215 void setNormalRef3f(Vector3f[] normals) { 9216 9217 if (normals != null) { 9218 if ((vertexType & NORMAL_DEFINED) != 0 && 9219 (vertexType & NORMAL_DEFINED) != N3F) { 9220 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray98")); 9221 } 9222 9223 if ((vertexFormat & GeometryArray.NORMALS) == 0) { 9224 throw new IllegalStateException(J3dI18N.getString("GeometryArray122")); 9225 } 9226 9227 if (this instanceof IndexedGeometryArrayRetained) { 9228 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9229 if (idx.maxNormalIndex >= normals.length) { 9230 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); 9231 } 9232 } else if (normals.length < (initialNormalIndex + validVertexCount) ) { 9233 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 9234 } 9235 } 9236 boolean isLive = source!=null && source.isLive(); 9237 if(isLive){ 9238 geomLock.getLock(); 9239 } 9240 dirtyFlag |= NORMAL_CHANGED; 9241 v3fRefNormals = normals; 9242 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9243 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9244 if (normals == null) 9245 vertexType &= ~N3F; 9246 else 9247 vertexType |= N3F; 9248 } 9249 else { 9250 setupMirrorNormalPointer(N3F); 9251 } 9252 if(isLive) { 9253 geomLock.unLock(); 9254 } 9255 if (!inUpdater && isLive) { 9256 sendDataChangedMessage(false); 9257 } 9258 } 9259 getNormalRef3f()9260 Vector3f[] getNormalRef3f() { 9261 return v3fRefNormals; 9262 } 9263 getColorStride()9264 final int getColorStride() { 9265 return ((vertexFormat & GeometryArray.WITH_ALPHA) != 0 ? 4 : 3); 9266 } 9267 getTexStride()9268 final int getTexStride() { 9269 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { 9270 return 2; 9271 } 9272 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 9273 return 3; 9274 } 9275 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 9276 return 4; 9277 } 9278 9279 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray121")); 9280 } 9281 setTexCoordRefFloat(int texCoordSet, float[] texCoords)9282 void setTexCoordRefFloat(int texCoordSet, float[] texCoords) { 9283 9284 if (texCoordType != 0 && texCoordType != TF) { 9285 if (texCoords != null) { 9286 throw new IllegalArgumentException( 9287 J3dI18N.getString("GeometryArray98")); 9288 } 9289 return; 9290 } 9291 9292 if (texCoords != null) { 9293 9294 int ts = getTexStride(); 9295 9296 if (this instanceof IndexedGeometryArrayRetained) { 9297 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9298 9299 if (idx.maxTexCoordIndices[texCoordSet]*ts >= texCoords.length) { 9300 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); 9301 } 9302 } else if (texCoords.length < ts*(initialTexCoordIndex[texCoordSet]+validVertexCount)) { 9303 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray113")); 9304 } 9305 } 9306 boolean isLive = source!=null && source.isLive(); 9307 if(isLive){ 9308 geomLock.getLock(); 9309 } 9310 dirtyFlag |= TEXTURE_CHANGED; 9311 refTexCoords[texCoordSet] = texCoords; 9312 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9313 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9314 texCoordType = TF; 9315 validateTexCoordPointerType(); 9316 } 9317 else { 9318 setupMirrorTexCoordPointer(texCoordSet, TF); 9319 } 9320 if(isLive) { 9321 geomLock.unLock(); 9322 } 9323 if (!inUpdater && isLive) { 9324 sendDataChangedMessage(false); 9325 } 9326 } 9327 9328 getTexCoordRefFloat(int texCoordSet)9329 float[] getTexCoordRefFloat(int texCoordSet) { 9330 return ((float[])refTexCoords[texCoordSet]); 9331 } 9332 9333 // set the tex coord with nio buffer setTexCoordRefBuffer(int texCoordSet, J3DBuffer texCoords)9334 void setTexCoordRefBuffer(int texCoordSet, J3DBuffer texCoords) { 9335 9336 FloatBufferWrapper bufferImpl = null; 9337 9338 if (texCoords != null) { 9339 if(texCoords.getBufferType() != J3DBuffer.TYPE_FLOAT) 9340 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116")); 9341 9342 bufferImpl = (FloatBufferWrapper)texCoords.getBufferImpl(); 9343 int bufferSize = bufferImpl.limit(); 9344 9345 assert bufferImpl.isDirect(); 9346 9347 int ts = getTexStride(); 9348 9349 if (this instanceof IndexedGeometryArrayRetained) { 9350 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9351 if (idx.maxTexCoordIndices[texCoordSet] * ts >= bufferSize) { 9352 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); 9353 } 9354 } else if (bufferSize < ts*(initialTexCoordIndex[texCoordSet] + validVertexCount)) { 9355 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray113")); 9356 } 9357 } 9358 boolean isLive = source!=null && source.isLive(); 9359 if(isLive){ 9360 geomLock.getLock(); 9361 } 9362 dirtyFlag |= TEXTURE_CHANGED; 9363 // refTexCoordsBuffer contains J3DBuffer object for tex coord 9364 refTexCoordsBuffer[texCoordSet] = texCoords; 9365 if (texCoords == null) { 9366 refTexCoords[texCoordSet] = null; 9367 } 9368 else { 9369 // refTexCoords contains NIOBuffer object for tex coord 9370 refTexCoords[texCoordSet] = bufferImpl.getBufferAsObject(); 9371 } 9372 texCoordType = TF; 9373 validateTexCoordPointerType(); 9374 if(isLive) { 9375 geomLock.unLock(); 9376 } 9377 if (!inUpdater && isLive) { 9378 sendDataChangedMessage(false); 9379 } 9380 } 9381 getTexCoordRefBuffer(int texCoordSet)9382 J3DBuffer getTexCoordRefBuffer(int texCoordSet) { 9383 return (J3DBuffer)(refTexCoordsBuffer[texCoordSet]); 9384 } 9385 setTexCoordRef2f(int texCoordSet, TexCoord2f[] texCoords)9386 void setTexCoordRef2f(int texCoordSet, TexCoord2f[] texCoords) { 9387 9388 if (texCoordType != 0 && texCoordType != T2F) { 9389 if (texCoords != null) { 9390 throw new IllegalArgumentException( 9391 J3dI18N.getString("GeometryArray98")); 9392 } 9393 return; 9394 } 9395 9396 if (texCoords != null) { 9397 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) == 0) { 9398 throw new IllegalStateException( 9399 J3dI18N.getString("GeometryArray94")); 9400 } 9401 9402 if (this instanceof IndexedGeometryArrayRetained) { 9403 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9404 9405 if (idx.maxTexCoordIndices[texCoordSet] >= texCoords.length) { 9406 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); 9407 } 9408 } else if (texCoords.length < (initialTexCoordIndex[texCoordSet] + validVertexCount) ) { 9409 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray113")); 9410 } 9411 9412 } 9413 boolean isLive = source!=null && source.isLive(); 9414 if(isLive){ 9415 geomLock.getLock(); 9416 } 9417 dirtyFlag |= TEXTURE_CHANGED; 9418 refTexCoords[texCoordSet] = texCoords; 9419 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9420 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9421 texCoordType = T2F; 9422 validateTexCoordPointerType(); 9423 } 9424 else { 9425 setupMirrorTexCoordPointer(texCoordSet, T2F); 9426 } 9427 if(isLive) { 9428 geomLock.unLock(); 9429 } 9430 if (!inUpdater && isLive) { 9431 sendDataChangedMessage(false); 9432 } 9433 } 9434 9435 getTexCoordRef2f(int texCoordSet)9436 TexCoord2f[] getTexCoordRef2f(int texCoordSet) { 9437 if (refTexCoords != null && refTexCoords[texCoordSet] != null && 9438 refTexCoords[texCoordSet] instanceof TexCoord2f[]) { 9439 return ((TexCoord2f[])refTexCoords[texCoordSet]); 9440 } else { 9441 return null; 9442 } 9443 } 9444 9445 setTexCoordRef3f(int texCoordSet, TexCoord3f[] texCoords)9446 void setTexCoordRef3f(int texCoordSet, TexCoord3f[] texCoords) { 9447 9448 if (texCoordType != 0 && texCoordType != T3F) { 9449 if (texCoords != null) { 9450 throw new IllegalArgumentException( 9451 J3dI18N.getString("GeometryArray98")); 9452 } 9453 return; 9454 } 9455 9456 if (texCoords != null) { 9457 9458 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) == 0) { 9459 throw new IllegalStateException( 9460 J3dI18N.getString("GeometryArray95")); 9461 } 9462 9463 if (this instanceof IndexedGeometryArrayRetained) { 9464 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9465 9466 if (idx.maxTexCoordIndices[texCoordSet] >= texCoords.length) { 9467 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); 9468 } 9469 9470 } else if (texCoords.length < (initialTexCoordIndex[texCoordSet] + validVertexCount) ) { 9471 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray113")); 9472 } 9473 9474 } 9475 boolean isLive = source!=null && source.isLive(); 9476 if(isLive){ 9477 geomLock.getLock(); 9478 } 9479 dirtyFlag |= TEXTURE_CHANGED; 9480 refTexCoords[texCoordSet] = texCoords; 9481 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9482 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9483 texCoordType = T3F; 9484 validateTexCoordPointerType(); 9485 } 9486 else { 9487 setupMirrorTexCoordPointer(texCoordSet, T3F); 9488 } 9489 if(isLive) { 9490 geomLock.unLock(); 9491 } 9492 if (!inUpdater && isLive) { 9493 sendDataChangedMessage(false); 9494 } 9495 } 9496 9497 getTexCoordRef3f(int texCoordSet)9498 TexCoord3f[] getTexCoordRef3f(int texCoordSet) { 9499 if (refTexCoords != null && refTexCoords[texCoordSet] != null && 9500 refTexCoords[texCoordSet] instanceof TexCoord3f[]) { 9501 return ((TexCoord3f[])refTexCoords[texCoordSet]); 9502 } else { 9503 return null; 9504 } 9505 } 9506 9507 9508 /** 9509 * Sets the float vertex attribute array reference for the 9510 * specified vertex attribute number to the specified array. 9511 */ setVertexAttrRefFloat(int vertexAttrNum, float[] vertexAttrs)9512 void setVertexAttrRefFloat(int vertexAttrNum, float[] vertexAttrs) { 9513 9514 // XXXX: Add the following test if we ever add double-precision types 9515 /* 9516 if (vertexAttrType != 0 && vertexAttrType != AF) { 9517 if (vertexAttrs != null) { 9518 // XXXX: new exception string 9519 throw new IllegalArgumentException( 9520 J3dI18N.getString("GeometryArray98-XXX")); 9521 } 9522 return; 9523 } 9524 */ 9525 9526 if (vertexAttrs != null) { 9527 int sz = vertexAttrSizes[vertexAttrNum]; 9528 9529 if (this instanceof IndexedGeometryArrayRetained) { 9530 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9531 9532 if (sz*idx.maxVertexAttrIndices[vertexAttrNum] >= vertexAttrs.length) { 9533 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30")); 9534 } 9535 9536 } else if (vertexAttrs.length < sz*(initialVertexAttrIndex[vertexAttrNum] + validVertexCount) ) { 9537 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray129")); 9538 } 9539 } 9540 boolean isLive = source!=null && source.isLive(); 9541 if(isLive){ 9542 geomLock.getLock(); 9543 } 9544 dirtyFlag |= VATTR_CHANGED; 9545 floatRefVertexAttrs[vertexAttrNum] = vertexAttrs; 9546 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9547 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9548 vertexAttrType = AF; 9549 validateVertexAttrPointerType(); 9550 } 9551 else { 9552 setupMirrorVertexAttrPointer(vertexAttrNum, AF); 9553 } 9554 if(isLive) { 9555 geomLock.unLock(); 9556 } 9557 if (!inUpdater && isLive) { 9558 sendDataChangedMessage(false); 9559 } 9560 } 9561 9562 /** 9563 * Gets the float vertex attribute array reference for the specified 9564 * vertex attribute number. 9565 */ getVertexAttrRefFloat(int vertexAttrNum)9566 float[] getVertexAttrRefFloat(int vertexAttrNum) { 9567 return floatRefVertexAttrs[vertexAttrNum]; 9568 } 9569 9570 9571 /** 9572 * Sets the vertex attribute buffer reference for the specified 9573 * vertex attribute number to the specified buffer object. 9574 */ setVertexAttrRefBuffer(int vertexAttrNum, J3DBuffer vertexAttrs)9575 void setVertexAttrRefBuffer(int vertexAttrNum, J3DBuffer vertexAttrs) { 9576 9577 FloatBufferWrapper bufferImpl = null; 9578 9579 if (vertexAttrs != null) { 9580 if(vertexAttrs.getBufferType() != J3DBuffer.TYPE_FLOAT) 9581 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116")); 9582 9583 bufferImpl = (FloatBufferWrapper)vertexAttrs.getBufferImpl(); 9584 int bufferSize = bufferImpl.limit(); 9585 9586 assert bufferImpl.isDirect(); 9587 9588 int sz = vertexAttrSizes[vertexAttrNum]; 9589 9590 if (this instanceof IndexedGeometryArrayRetained) { 9591 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9592 9593 if (idx.maxVertexAttrIndices[vertexAttrNum] * sz >= bufferSize) { 9594 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30")); 9595 } 9596 } else if (bufferSize < sz*(initialVertexAttrIndex[vertexAttrNum] + validVertexCount)) { 9597 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray129")); 9598 } 9599 } 9600 boolean isLive = source!=null && source.isLive(); 9601 if(isLive){ 9602 geomLock.getLock(); 9603 } 9604 dirtyFlag |= VATTR_CHANGED; 9605 vertexAttrsRefBuffer[vertexAttrNum] = vertexAttrs; 9606 if (vertexAttrs == null) { 9607 floatBufferRefVertexAttrs[vertexAttrNum] = null; 9608 nioFloatBufferRefVertexAttrs[vertexAttrNum] = null; 9609 } 9610 else { 9611 floatBufferRefVertexAttrs[vertexAttrNum] = bufferImpl; 9612 nioFloatBufferRefVertexAttrs[vertexAttrNum] = 9613 bufferImpl.getBufferAsObject(); 9614 } 9615 vertexAttrType = AF; 9616 validateVertexAttrPointerType(); 9617 if(isLive) { 9618 geomLock.unLock(); 9619 } 9620 if (!inUpdater && isLive) { 9621 sendDataChangedMessage(false); 9622 } 9623 9624 } 9625 9626 /** 9627 * Gets the vertex attribute array buffer reference for the specified 9628 * vertex attribute number. 9629 */ getVertexAttrRefBuffer(int vertexAttrNum)9630 J3DBuffer getVertexAttrRefBuffer(int vertexAttrNum) { 9631 return vertexAttrsRefBuffer[vertexAttrNum]; 9632 } 9633 9634 setInterleavedVertices(float[] vertexData)9635 void setInterleavedVertices(float[] vertexData) { 9636 if (vertexData != null) { 9637 9638 if (this instanceof IndexedGeometryArrayRetained) { 9639 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9640 9641 if (stride * idx.maxCoordIndex >= vertexData.length) { 9642 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 9643 } 9644 9645 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 9646 for (int i = 0; i < texCoordSetCount; i++) { 9647 if (stride * idx.maxTexCoordIndices[i] >= vertexData.length) { 9648 throw new ArrayIndexOutOfBoundsException( 9649 J3dI18N.getString("IndexedGeometryArray25")); 9650 } 9651 } 9652 } 9653 9654 if (((this.vertexFormat & GeometryArray.COLOR) != 0) && 9655 (stride * idx.maxColorIndex >= vertexData.length)) { 9656 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 9657 } 9658 9659 if (((this.vertexFormat & GeometryArray.NORMALS) != 0) && 9660 (stride * idx.maxNormalIndex >= vertexData.length)) { 9661 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); 9662 } 9663 } else { 9664 if (vertexData.length < (stride * (initialVertexIndex+validVertexCount))) 9665 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray114")); 9666 } 9667 } 9668 9669 // If the geometry has been rendered transparent, then make a copy 9670 // of the color pointer with 4f 9671 boolean isLive = source!=null && source.isLive(); 9672 if(isLive){ 9673 geomLock.getLock(); 9674 } 9675 dirtyFlag |= VERTEX_CHANGED; 9676 colorChanged = 0xffff; 9677 interLeavedVertexData = vertexData; 9678 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9679 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9680 setupMirrorInterleavedColorPointer(false); 9681 } 9682 if(isLive) { 9683 geomLock.unLock(); 9684 } 9685 if (!inUpdater && isLive) { 9686 processCoordsChanged(vertexData == null); 9687 sendDataChangedMessage(true); 9688 } 9689 } 9690 9691 // set the interleaved vertex with NIO buffer setInterleavedVertexBuffer(J3DBuffer vertexData)9692 void setInterleavedVertexBuffer(J3DBuffer vertexData) { 9693 9694 FloatBufferWrapper bufferImpl = null; 9695 9696 if (vertexData != null ){ 9697 9698 if (vertexData.getBufferType() != J3DBuffer.TYPE_FLOAT) 9699 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray116")); 9700 9701 bufferImpl = (FloatBufferWrapper)vertexData.getBufferImpl(); 9702 9703 assert bufferImpl.isDirect(); 9704 9705 int bufferSize = bufferImpl.limit(); 9706 9707 if (this instanceof IndexedGeometryArrayRetained) { 9708 IndexedGeometryArrayRetained idx = (IndexedGeometryArrayRetained)this; 9709 9710 if (stride * idx.maxCoordIndex >= bufferSize) { 9711 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 9712 } 9713 9714 if ((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 9715 for (int i = 0; i < texCoordSetCount; i++) { 9716 if (stride * idx.maxTexCoordIndices[i] >= bufferSize) { 9717 throw new ArrayIndexOutOfBoundsException( 9718 J3dI18N.getString("IndexedGeometryArray25")); 9719 } 9720 } 9721 } 9722 9723 if (((this.vertexFormat & GeometryArray.COLOR) != 0) && 9724 (stride * idx.maxColorIndex >= bufferSize)) { 9725 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); 9726 } 9727 9728 if (((this.vertexFormat & GeometryArray.NORMALS) != 0) && 9729 (stride * idx.maxNormalIndex >= bufferSize)) { 9730 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); 9731 } 9732 } else { 9733 if (bufferSize < (stride * (initialVertexIndex+validVertexCount))) 9734 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray114")); 9735 } 9736 } 9737 // If the geometry has been rendered transparent, then make a copy 9738 // of the color pointer with 4f 9739 boolean isLive = source!=null && source.isLive(); 9740 if(isLive){ 9741 geomLock.getLock(); 9742 } 9743 dirtyFlag |= VERTEX_CHANGED; 9744 colorChanged = 0xffff; 9745 interleavedVertexBuffer = vertexData; 9746 9747 if(vertexData == null) 9748 interleavedFloatBufferImpl = null; 9749 else 9750 interleavedFloatBufferImpl = bufferImpl; 9751 9752 if (inUpdater || (this instanceof IndexedGeometryArrayRetained && 9753 ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0))) { 9754 setupMirrorInterleavedColorPointer(false); 9755 } 9756 if(isLive) { 9757 geomLock.unLock(); 9758 } 9759 if (!inUpdater && isLive) { 9760 processCoordsChanged(vertexData == null); 9761 sendDataChangedMessage(true); 9762 } 9763 } 9764 getInterleavedVertices()9765 float[] getInterleavedVertices() { 9766 return interLeavedVertexData; 9767 } 9768 getInterleavedVertexBuffer()9769 J3DBuffer getInterleavedVertexBuffer() { 9770 return interleavedVertexBuffer; 9771 } 9772 setValidVertexCount(int validVertexCount)9773 void setValidVertexCount(int validVertexCount) { 9774 9775 boolean nullGeo = false; 9776 if (validVertexCount < 0) { 9777 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray110")); 9778 } 9779 9780 if ((initialVertexIndex + validVertexCount) > vertexCount) { 9781 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray100")); 9782 } 9783 9784 if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { 9785 // Interleaved, by-ref 9786 9787 // use nio buffer for interleaved data 9788 if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0 && interleavedFloatBufferImpl != null){ 9789 if(interleavedFloatBufferImpl.limit() < stride * (initialVertexIndex + validVertexCount)) { 9790 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray114")); 9791 } 9792 } 9793 //use java array for interleaved data 9794 else if( interLeavedVertexData != null) { 9795 if(interLeavedVertexData.length < stride * (initialVertexIndex + validVertexCount)) { 9796 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray114")); 9797 } 9798 } 9799 else { 9800 nullGeo = true; 9801 } 9802 } else if ((vertexFormat & GeometryArray.BY_REFERENCE) != 0) { 9803 // Non-interleaved, by-ref 9804 9805 if ((initialCoordIndex + validVertexCount) > vertexCount) { 9806 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray104")); 9807 } 9808 if ((initialColorIndex + validVertexCount) > vertexCount) { 9809 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray101")); 9810 } 9811 if ((initialNormalIndex + validVertexCount) > vertexCount) { 9812 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray102")); 9813 } 9814 9815 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 9816 for (int i = 0; i < texCoordSetCount; i++) { 9817 if ((initialTexCoordIndex[i] + validVertexCount) > vertexCount) { 9818 throw new IllegalArgumentException(J3dI18N.getString( 9819 "GeometryArray103")); 9820 } 9821 } 9822 } 9823 9824 if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 9825 for (int i = 0; i < vertexAttrCount; i++) { 9826 if ((initialVertexAttrIndex[i] + validVertexCount) > vertexCount) { 9827 throw new IllegalArgumentException(J3dI18N.getString( 9828 "GeometryArray130")); 9829 } 9830 } 9831 } 9832 9833 if ((vertexType & GeometryArrayRetained.VERTEX_DEFINED) == 0) { 9834 nullGeo = true; 9835 } 9836 9837 if (( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { 9838 // by reference with nio buffer 9839 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 9840 case PF: 9841 if(floatBufferRefCoords.limit() < 3 * (initialCoordIndex+validVertexCount) ) { 9842 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 9843 } 9844 break; 9845 case PD: 9846 if(doubleBufferRefCoords.limit() < 3 * (initialCoordIndex+validVertexCount) ) { 9847 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 9848 } 9849 break; 9850 } 9851 9852 switch ((vertexType & COLOR_DEFINED)) { 9853 case CF: 9854 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 9855 if (floatBufferRefColors.limit() < 3 * (initialColorIndex+validVertexCount)) { 9856 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9857 } 9858 } 9859 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 9860 if (floatBufferRefColors.limit() < 4 * (initialColorIndex+validVertexCount)) { 9861 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9862 } 9863 } 9864 break; 9865 case CUB: 9866 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 9867 if (byteBufferRefColors.limit() < 3 * (initialColorIndex + validVertexCount)) { 9868 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9869 } 9870 } 9871 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 9872 if (byteBufferRefColors.limit() < 4 * (initialColorIndex + validVertexCount) ) { 9873 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9874 } 9875 } 9876 break; 9877 } 9878 switch ((vertexType & GeometryArrayRetained.TEXCOORD_DEFINED)) { 9879 case TF: 9880 FloatBufferWrapper texBuffer; 9881 for (int i = 0; i < texCoordSetCount; i++) { 9882 texBuffer = (FloatBufferWrapper)(((J3DBuffer)refTexCoordsBuffer[i]).getBufferImpl()); 9883 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { 9884 if (texBuffer.limit() < 2 * (initialTexCoordIndex[i] + validVertexCount) ) { 9885 throw new ArrayIndexOutOfBoundsException( 9886 J3dI18N.getString("GeometryArray113")); 9887 } 9888 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 9889 if (texBuffer.limit() < 3 * (initialTexCoordIndex[i] + validVertexCount) ) { 9890 throw new ArrayIndexOutOfBoundsException( 9891 J3dI18N.getString("GeometryArray113")); 9892 } 9893 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 9894 if (texBuffer.limit() < 4 * (initialTexCoordIndex[i] + validVertexCount)) { 9895 throw new ArrayIndexOutOfBoundsException( 9896 J3dI18N.getString("GeometryArray113")); 9897 } 9898 } 9899 } 9900 break; 9901 } 9902 switch ((vertexType & GeometryArrayRetained.NORMAL_DEFINED)) { 9903 case NF: 9904 if (floatBufferRefNormals.limit() < 3 * (initialNormalIndex + validVertexCount )) { 9905 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 9906 } 9907 break; 9908 } 9909 switch ((vertexType & GeometryArrayRetained.VATTR_DEFINED)) { 9910 case AF: 9911 for (int i = 0; i < vertexAttrCount; i++) { 9912 int sz = vertexAttrSizes[i]; 9913 if (floatBufferRefVertexAttrs[i].limit() < 9914 (sz * (initialVertexAttrIndex[i] + validVertexCount)) ) { 9915 throw new ArrayIndexOutOfBoundsException( 9916 J3dI18N.getString("GeometryArray129")); 9917 } 9918 } 9919 break; 9920 } 9921 } 9922 // By reference with java array 9923 else { 9924 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 9925 case PF: 9926 if (floatRefCoords.length < 3 * (initialCoordIndex+validVertexCount)) { 9927 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 9928 } 9929 break; 9930 case PD: 9931 if (doubleRefCoords.length < 3 * (initialCoordIndex+validVertexCount)) { 9932 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 9933 } 9934 break; 9935 case P3F: 9936 if (p3fRefCoords.length < (initialCoordIndex+validVertexCount) ) { 9937 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 9938 } 9939 break; 9940 case P3D: 9941 if (p3dRefCoords.length < (initialCoordIndex+validVertexCount) ) { 9942 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 9943 } 9944 break; 9945 } 9946 switch ((vertexType & COLOR_DEFINED)) { 9947 case CF: 9948 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 9949 if (floatRefColors.length < 3 * (initialColorIndex+validVertexCount)) { 9950 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9951 } 9952 } 9953 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 9954 if (floatRefColors.length < 4 * (initialColorIndex+ validVertexCount) ) { 9955 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9956 } 9957 } 9958 break; 9959 case CUB: 9960 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 9961 if (byteRefColors.length < 3 * (initialColorIndex + validVertexCount)) { 9962 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9963 } 9964 } 9965 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 9966 if (byteRefColors.length < 4 * (initialColorIndex + validVertexCount) ) { 9967 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9968 } 9969 } 9970 break; 9971 case C3F: 9972 if (c3fRefColors.length < (initialColorIndex + validVertexCount) ) { 9973 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9974 } 9975 break; 9976 case C4F: 9977 if (c4fRefColors.length < (initialColorIndex + validVertexCount) ) { 9978 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9979 } 9980 break; 9981 case C3UB: 9982 if (c3bRefColors.length < (initialColorIndex + validVertexCount)) { 9983 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9984 } 9985 break; 9986 case C4UB: 9987 if (c4bRefColors.length < (initialColorIndex + validVertexCount) ) { 9988 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 9989 } 9990 break; 9991 } 9992 switch ((vertexType & GeometryArrayRetained.TEXCOORD_DEFINED)) { 9993 case TF: 9994 for (int i = 0; i < texCoordSetCount; i++) { 9995 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { 9996 if (((float[])refTexCoords[i]).length < 2 * (initialTexCoordIndex[i] + validVertexCount) ) { 9997 throw new ArrayIndexOutOfBoundsException( 9998 J3dI18N.getString("GeometryArray113")); 9999 } 10000 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 10001 if (((float[])refTexCoords[i]).length < 3 * (initialTexCoordIndex[i] + validVertexCount) ) { 10002 throw new ArrayIndexOutOfBoundsException( 10003 J3dI18N.getString("GeometryArray113")); 10004 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 10005 if (((float[])refTexCoords[i]).length < 4 * (initialTexCoordIndex[i] + validVertexCount)) { 10006 throw new ArrayIndexOutOfBoundsException( 10007 J3dI18N.getString("GeometryArray113")); 10008 } 10009 } 10010 } 10011 } 10012 break; 10013 case T2F: 10014 for (int i = 0; i < texCoordSetCount; i++) { 10015 if (((TexCoord2f[])refTexCoords[i]).length < (initialTexCoordIndex[i] + validVertexCount) ) { 10016 throw new ArrayIndexOutOfBoundsException( 10017 J3dI18N.getString("GeometryArray113")); 10018 } 10019 } 10020 break; 10021 case T3F: 10022 for (int i = 0; i < texCoordSetCount; i++) { 10023 if (((TexCoord3f[])refTexCoords[i]).length < (initialTexCoordIndex[i] + validVertexCount) ) { 10024 throw new ArrayIndexOutOfBoundsException( 10025 J3dI18N.getString("GeometryArray113")); 10026 } 10027 } 10028 break; 10029 } 10030 switch ((vertexType & GeometryArrayRetained.NORMAL_DEFINED)) { 10031 case NF: 10032 if (floatRefNormals.length < 3 * (initialNormalIndex + validVertexCount )) { 10033 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 10034 } 10035 break; 10036 case N3F: 10037 if (v3fRefNormals.length < (initialNormalIndex + validVertexCount) ) { 10038 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 10039 } 10040 } 10041 switch ((vertexType & GeometryArrayRetained.VATTR_DEFINED)) { 10042 case AF: 10043 for (int i = 0; i < vertexAttrCount; i++) { 10044 int sz = vertexAttrSizes[i]; 10045 if (floatRefVertexAttrs[i].length < 10046 (sz * (initialVertexAttrIndex[i] + validVertexCount)) ) { 10047 throw new ArrayIndexOutOfBoundsException( 10048 J3dI18N.getString("GeometryArray129")); 10049 } 10050 } 10051 break; 10052 } 10053 } 10054 } 10055 boolean isLive = source!=null && source.isLive(); 10056 if(isLive){ 10057 geomLock.getLock(); 10058 } 10059 dirtyFlag |= VERTEX_CHANGED; 10060 this.validVertexCount = validVertexCount; 10061 10062 if(isLive){ 10063 geomLock.unLock(); 10064 } 10065 10066 if (!inUpdater && isLive) { 10067 processCoordsChanged(nullGeo); 10068 sendDataChangedMessage(true); 10069 } 10070 } 10071 10072 getValidVertexCount()10073 int getValidVertexCount() { 10074 return validVertexCount; 10075 } 10076 10077 //Used for interleaved data (array or nio buffer) setInitialVertexIndex(int initialVertexIndex)10078 void setInitialVertexIndex(int initialVertexIndex) { 10079 boolean nullGeo = false; 10080 10081 if ((initialVertexIndex + validVertexCount) > vertexCount) { 10082 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray100")); 10083 } 10084 10085 if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0 && interleavedFloatBufferImpl != null) { 10086 if(interleavedFloatBufferImpl.limit() < stride * (initialVertexIndex + validVertexCount)) { 10087 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray114")); 10088 } 10089 } 10090 // interleaved data using java array 10091 else if(interLeavedVertexData != null) { 10092 if (interLeavedVertexData.length < stride * (initialVertexIndex + validVertexCount)) { 10093 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray114")); 10094 } 10095 } 10096 else { 10097 nullGeo = (vertexFormat & GeometryArray.INTERLEAVED) != 0; // Only for byRef 10098 } 10099 boolean isLive = source!=null && source.isLive(); 10100 if(isLive){ 10101 geomLock.getLock(); 10102 } 10103 dirtyFlag |= VERTEX_CHANGED; 10104 this.initialVertexIndex = initialVertexIndex; 10105 if(isLive) { 10106 geomLock.unLock(); 10107 } 10108 if (!inUpdater && isLive) { 10109 processCoordsChanged(nullGeo); 10110 sendDataChangedMessage(true); 10111 } 10112 } 10113 getInitialVertexIndex()10114 int getInitialVertexIndex() { 10115 return initialVertexIndex; 10116 } 10117 setInitialCoordIndex(int initialCoordIndex)10118 void setInitialCoordIndex(int initialCoordIndex) { 10119 if ((initialCoordIndex + validVertexCount) > vertexCount) { 10120 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray104")); 10121 } 10122 // use NIO buffer 10123 if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0){ 10124 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 10125 case PF: 10126 if(floatBufferRefCoords.limit() < (initialCoordIndex+validVertexCount) ) { 10127 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 10128 } 10129 break; 10130 case PD: 10131 if(doubleBufferRefCoords.limit() < (initialCoordIndex+validVertexCount) ) { 10132 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 10133 } 10134 break; 10135 } 10136 } else { 10137 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 10138 case PF: 10139 if (floatRefCoords.length < 3 * (initialCoordIndex+validVertexCount)) { 10140 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 10141 } 10142 break; 10143 case PD: 10144 if (doubleRefCoords.length < 3 * (initialCoordIndex+validVertexCount)) { 10145 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 10146 } 10147 break; 10148 case P3F: 10149 if (p3fRefCoords.length < (initialCoordIndex+validVertexCount) ) { 10150 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 10151 } 10152 break; 10153 case P3D: 10154 if (p3dRefCoords.length < (initialCoordIndex+validVertexCount) ) { 10155 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray99")); 10156 } 10157 break; 10158 } 10159 } 10160 boolean isLive = source!=null && source.isLive(); 10161 if(isLive){ 10162 geomLock.getLock(); 10163 } 10164 dirtyFlag |= COORDINATE_CHANGED; 10165 this.initialCoordIndex = initialCoordIndex; 10166 dirtyFlag |= COORDINATE_CHANGED; 10167 if(isLive) { 10168 geomLock.unLock(); 10169 } 10170 // Send a message, since bounds changed 10171 if (!inUpdater && isLive) { 10172 processCoordsChanged((vertexType & GeometryArrayRetained.VERTEX_DEFINED) == 0); 10173 sendDataChangedMessage(true); 10174 } 10175 } 10176 getInitialCoordIndex()10177 int getInitialCoordIndex() { 10178 return initialCoordIndex; 10179 } 10180 setInitialColorIndex(int initialColorIndex)10181 void setInitialColorIndex(int initialColorIndex) { 10182 if ((initialColorIndex + validVertexCount) > vertexCount) { 10183 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray101")); 10184 } 10185 // NIO BUFFER CASE 10186 if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0){ 10187 switch ((vertexType & COLOR_DEFINED)) { 10188 case CF: 10189 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10190 if (floatBufferRefColors.limit() < 3 * (initialColorIndex+validVertexCount)) { 10191 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10192 } 10193 } 10194 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 10195 if (floatBufferRefColors.limit() < 4 * (initialColorIndex+validVertexCount)) { 10196 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10197 } 10198 } 10199 break; 10200 10201 case CUB: 10202 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10203 if (byteBufferRefColors.limit() < 3 * (initialColorIndex + validVertexCount)) { 10204 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10205 } 10206 } 10207 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 10208 if (byteBufferRefColors.limit() < 4 * (initialColorIndex + validVertexCount) ) { 10209 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10210 } 10211 } 10212 break; 10213 } 10214 } 10215 // Java ARRAY CASE 10216 else { 10217 switch ((vertexType & COLOR_DEFINED)) { 10218 case CF: 10219 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10220 if (floatRefColors.length < 3 * (initialColorIndex+validVertexCount)) { 10221 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10222 } 10223 } 10224 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 10225 if (floatRefColors.length < 4 * (initialColorIndex+ validVertexCount) ) { 10226 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10227 } 10228 } 10229 break; 10230 case CUB: 10231 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10232 if (byteRefColors.length < 3 * (initialColorIndex + validVertexCount)) { 10233 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10234 } 10235 } 10236 else if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_4) { 10237 if (byteRefColors.length < 4 * (initialColorIndex + validVertexCount) ) { 10238 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10239 } 10240 } 10241 break; 10242 case C3F: 10243 if (c3fRefColors.length < (initialColorIndex + validVertexCount) ) { 10244 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10245 } 10246 break; 10247 case C4F: 10248 if (c4fRefColors.length < (initialColorIndex + validVertexCount) ) { 10249 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10250 } 10251 break; 10252 case C3UB: 10253 if (c3bRefColors.length < (initialColorIndex + validVertexCount)) { 10254 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10255 } 10256 break; 10257 case C4UB: 10258 if (c4bRefColors.length < (initialColorIndex + validVertexCount) ) { 10259 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray112")); 10260 } 10261 break; 10262 } 10263 } 10264 boolean isLive = source!=null && source.isLive(); 10265 if(isLive){ 10266 geomLock.getLock(); 10267 } 10268 dirtyFlag |= COLOR_CHANGED; 10269 colorChanged = 0xffff; 10270 this.initialColorIndex = initialColorIndex; 10271 if(isLive) { 10272 geomLock.unLock(); 10273 } 10274 // There is no need to send message for by reference, since we 10275 // use VA 10276 10277 } 10278 getInitialColorIndex()10279 int getInitialColorIndex() { 10280 return initialColorIndex; 10281 } 10282 setInitialNormalIndex(int initialNormalIndex)10283 void setInitialNormalIndex(int initialNormalIndex) { 10284 if ((initialNormalIndex + validVertexCount) > vertexCount) { 10285 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray102")); 10286 } 10287 if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0){ 10288 if((vertexType & NORMAL_DEFINED) == NF){ 10289 if (floatBufferRefNormals.limit() < 3 * (initialNormalIndex + validVertexCount )) { 10290 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 10291 } 10292 } 10293 } else { 10294 switch((vertexType & NORMAL_DEFINED)){ 10295 case NF: 10296 if (floatRefNormals.length < 3 * (initialNormalIndex + validVertexCount )) { 10297 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 10298 } 10299 break; 10300 case N3F: 10301 if (v3fRefNormals.length < (initialNormalIndex + validVertexCount) ) { 10302 throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("GeometryArray111")); 10303 } 10304 } 10305 } 10306 boolean isLive = source!=null && source.isLive(); 10307 if(isLive){ 10308 geomLock.getLock(); 10309 } 10310 dirtyFlag |= NORMAL_CHANGED; 10311 this.initialNormalIndex = initialNormalIndex; 10312 if(isLive) { 10313 geomLock.unLock(); 10314 } 10315 // There is no need to send message for by reference, since we 10316 // use VA 10317 } 10318 getInitialNormalIndex()10319 int getInitialNormalIndex() { 10320 return initialNormalIndex; 10321 } 10322 10323 /** 10324 * Sets the initial vertex attribute index for the specified 10325 * vertex attribute number for this GeometryArray object. 10326 */ setInitialVertexAttrIndex(int vertexAttrNum, int initialVertexAttrIndex)10327 void setInitialVertexAttrIndex(int vertexAttrNum, 10328 int initialVertexAttrIndex) { 10329 10330 if ((initialVertexAttrIndex + validVertexCount) > vertexCount) { 10331 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray130")); 10332 } 10333 10334 int sz = vertexAttrSizes[vertexAttrNum]; 10335 int minLength = sz * (initialVertexAttrIndex + validVertexCount); 10336 if ((vertexType & VATTR_DEFINED) == AF) { 10337 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { 10338 if (floatBufferRefVertexAttrs[vertexAttrNum].limit() < minLength) { 10339 throw new ArrayIndexOutOfBoundsException( 10340 J3dI18N.getString("GeometryArray129")); 10341 } 10342 } else { 10343 if (floatRefVertexAttrs[vertexAttrNum].length < minLength ) { 10344 throw new ArrayIndexOutOfBoundsException( 10345 J3dI18N.getString("GeometryArray129")); 10346 } 10347 } 10348 } 10349 boolean isLive = source!=null && source.isLive(); 10350 if(isLive){ 10351 geomLock.getLock(); 10352 } 10353 dirtyFlag |= VATTR_CHANGED; 10354 this.initialVertexAttrIndex[vertexAttrNum] = initialVertexAttrIndex; 10355 if(isLive) { 10356 geomLock.unLock(); 10357 } 10358 // There is no need to send message for by reference, since we 10359 // use VA 10360 } 10361 10362 10363 /** 10364 * Gets the initial vertex attribute index for the specified 10365 * vertex attribute number for this GeometryArray object. 10366 */ getInitialVertexAttrIndex(int vertexAttrNum)10367 int getInitialVertexAttrIndex(int vertexAttrNum) { 10368 return initialVertexAttrIndex[vertexAttrNum]; 10369 } 10370 setInitialTexCoordIndex(int texCoordSet, int initialTexCoordIndex)10371 void setInitialTexCoordIndex(int texCoordSet, int initialTexCoordIndex) { 10372 if ((initialTexCoordIndex + validVertexCount) > vertexCount) { 10373 throw new IllegalArgumentException(J3dI18N.getString("GeometryArray103")); 10374 } 10375 10376 if((vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0){ 10377 if((vertexType & TEXCOORD_DEFINED) == TF) { 10378 FloatBufferWrapper texBuffer = (FloatBufferWrapper)(((J3DBuffer) refTexCoordsBuffer[texCoordSet]).getBufferImpl()); 10379 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { 10380 if (texBuffer.limit() < 2 * (initialTexCoordIndex+ validVertexCount) ) { 10381 throw new ArrayIndexOutOfBoundsException( 10382 J3dI18N.getString("GeometryArray113")); 10383 } 10384 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 10385 if (texBuffer.limit() < 3 * (initialTexCoordIndex + validVertexCount) ) { 10386 throw new ArrayIndexOutOfBoundsException( 10387 J3dI18N.getString("GeometryArray113")); 10388 } 10389 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 10390 if (texBuffer.limit() < 4 * (initialTexCoordIndex + validVertexCount)) { 10391 throw new ArrayIndexOutOfBoundsException( 10392 J3dI18N.getString("GeometryArray113")); 10393 } 10394 } 10395 } 10396 } else { 10397 switch ((vertexType & TEXCOORD_DEFINED)) { 10398 case TF: 10399 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { 10400 if (((float[])refTexCoords[texCoordSet]).length < 2 * (initialTexCoordIndex+ validVertexCount) ) { 10401 throw new ArrayIndexOutOfBoundsException( 10402 J3dI18N.getString("GeometryArray113")); 10403 } 10404 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 10405 if (((float[])refTexCoords[texCoordSet]).length < 3 * (initialTexCoordIndex + validVertexCount) ) { 10406 throw new ArrayIndexOutOfBoundsException( 10407 J3dI18N.getString("GeometryArray113")); 10408 } 10409 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 10410 if (((float[])refTexCoords[texCoordSet]).length < 4 * (initialTexCoordIndex + validVertexCount)) { 10411 throw new ArrayIndexOutOfBoundsException( 10412 J3dI18N.getString("GeometryArray113")); 10413 } 10414 } 10415 break; 10416 case T2F: 10417 if (((TexCoord2f[])refTexCoords[texCoordSet]).length < (initialTexCoordIndex+ validVertexCount) ) { 10418 throw new ArrayIndexOutOfBoundsException( 10419 J3dI18N.getString("GeometryArray113")); 10420 } 10421 break; 10422 case T3F: 10423 if (((TexCoord3f[])refTexCoords[texCoordSet]).length < (initialTexCoordIndex+ validVertexCount) ) { 10424 throw new ArrayIndexOutOfBoundsException( 10425 J3dI18N.getString("GeometryArray113")); 10426 } 10427 break; 10428 } 10429 } 10430 boolean isLive = source!=null && source.isLive(); 10431 if(isLive){ 10432 geomLock.getLock(); 10433 } 10434 dirtyFlag |= TEXTURE_CHANGED; 10435 this.initialTexCoordIndex[texCoordSet] = initialTexCoordIndex; 10436 if(isLive) { 10437 geomLock.unLock(); 10438 } 10439 // There is no need to send message for by reference, since we 10440 // use VA 10441 } 10442 getInitialTexCoordIndex(int texCoordSet)10443 int getInitialTexCoordIndex(int texCoordSet) { 10444 return initialTexCoordIndex[texCoordSet]; 10445 } 10446 10447 getTexCoordSetCount()10448 int getTexCoordSetCount() { 10449 return this.texCoordSetCount; 10450 } 10451 getTexCoordSetMapLength()10452 int getTexCoordSetMapLength() { 10453 if (this.texCoordSetMap != null) 10454 return this.texCoordSetMap.length; 10455 else 10456 return 0; 10457 } 10458 getTexCoordSetMap(int [] texCoordSetMap)10459 void getTexCoordSetMap(int [] texCoordSetMap) { 10460 10461 if (this.texCoordSetMap!=null) { 10462 for (int i = 0; i < this.texCoordSetMap.length; i++) { 10463 texCoordSetMap[i] = this.texCoordSetMap[i]; 10464 } 10465 } 10466 } 10467 freeDlistId()10468 void freeDlistId() { 10469 if (dlistId != -1) { 10470 VirtualUniverse.mc.freeDisplayListId(dlistObj); 10471 dlistId = -1; 10472 } 10473 } 10474 assignDlistId()10475 void assignDlistId() { 10476 if (dlistId == -1) { 10477 dlistObj = VirtualUniverse.mc.getDisplayListId(); 10478 dlistId = dlistObj.intValue(); 10479 } 10480 } 10481 10482 // Add the specified render atom as a user of this geometry array 10483 // (for the specified render bin) addDlistUser(RenderBin renderBin, RenderAtomListInfo ra)10484 void addDlistUser(RenderBin renderBin, RenderAtomListInfo ra) { 10485 if (dlistUsers == null) { 10486 dlistUsers = new HashMap(2, 1.0f); 10487 } 10488 10489 Set raSet = (Set)dlistUsers.get(renderBin); 10490 if (raSet == null) { 10491 raSet = new HashSet(); 10492 dlistUsers.put(renderBin, raSet); 10493 } 10494 raSet.add(ra); 10495 } 10496 10497 // Remove the specified render atom from the set of users of this 10498 // geometry array (for the specified render bin) removeDlistUser(RenderBin renderBin, RenderAtomListInfo ra)10499 void removeDlistUser(RenderBin renderBin, RenderAtomListInfo ra) { 10500 if (dlistUsers == null) { 10501 // Nothing to do 10502 return; 10503 } 10504 10505 Set raSet = (Set)dlistUsers.get(renderBin); 10506 if (raSet == null) { 10507 // Nothing to do 10508 return; 10509 } 10510 raSet.remove(ra); 10511 } 10512 10513 // Returns true if the set of render atoms using this geometry 10514 // array in the specified render bin is empty. isDlistUserSetEmpty(RenderBin renderBin)10515 boolean isDlistUserSetEmpty(RenderBin renderBin) { 10516 if (dlistUsers == null) { 10517 return true; 10518 } 10519 10520 Set raSet = (Set)dlistUsers.get(renderBin); 10521 if (raSet == null) { 10522 return true; 10523 } 10524 return raSet.isEmpty(); 10525 } 10526 10527 // This method is used for debugging only numDlistUsers(RenderBin renderBin)10528 int numDlistUsers(RenderBin renderBin) { 10529 if (isDlistUserSetEmpty(renderBin)) { 10530 return 0; 10531 } 10532 Set raSet = (Set)dlistUsers.get(renderBin); 10533 return raSet.size(); 10534 } 10535 setDlistTimeStamp(int rdrBit, long timeStamp)10536 void setDlistTimeStamp(int rdrBit, long timeStamp) { 10537 int index = getIndex(rdrBit); 10538 if (index >= timeStampPerDlist.length) { 10539 long[] newList = new long[index * 2]; 10540 for (int i = 0; i < timeStampPerDlist.length; i++) { 10541 newList[i] = timeStampPerDlist[i]; 10542 } 10543 timeStampPerDlist = newList; 10544 } 10545 timeStampPerDlist[index] = timeStamp; 10546 } 10547 getDlistTimeStamp(int rdrBit)10548 long getDlistTimeStamp(int rdrBit) { 10549 int index = getIndex(rdrBit); 10550 // If index is greater than what currently exists, increase 10551 // the array and return zero 10552 if (index >= timeStampPerDlist.length) { 10553 setDlistTimeStamp(rdrBit, 0); 10554 } 10555 return timeStampPerDlist[index]; 10556 } 10557 getIndex(int bit)10558 int getIndex(int bit) { 10559 int num = 0; 10560 10561 while (bit > 0) { 10562 num++; 10563 bit >>= 1; 10564 } 10565 return num; 10566 } 10567 10568 isWriteStatic()10569 boolean isWriteStatic() { 10570 10571 if (source.getCapability(GeometryArray.ALLOW_COORDINATE_WRITE ) || 10572 source.getCapability(GeometryArray.ALLOW_COLOR_WRITE) || 10573 source.getCapability(GeometryArray.ALLOW_NORMAL_WRITE) || 10574 source.getCapability(GeometryArray.ALLOW_TEXCOORD_WRITE) || 10575 source.getCapability(GeometryArray.ALLOW_VERTEX_ATTR_WRITE) || 10576 source.getCapability(GeometryArray.ALLOW_COUNT_WRITE) || 10577 source.getCapability(GeometryArray.ALLOW_REF_DATA_WRITE)) 10578 return false; 10579 10580 return true; 10581 } 10582 10583 /** 10584 * The functions below are only used in compile mode 10585 */ setCompiled(ArrayList curList)10586 void setCompiled(ArrayList curList) { 10587 int i; 10588 int num = curList.size(); 10589 int offset = 0; 10590 geoOffset = new int[num]; 10591 compileVcount = new int[num]; 10592 int vcount = 0, vformat = 0; 10593 vcount = 0; 10594 isCompiled = true; 10595 10596 if (num > 0) 10597 source = ((SceneGraphObjectRetained)curList.get(0)).source; 10598 for (i = 0; i < num; i++) { 10599 // Build the back mapping 10600 GeometryArrayRetained geo = (GeometryArrayRetained)curList.get(i); 10601 ((GeometryArray)geo.source).retained = this; 10602 compileVcount[i] = geo.getValidVertexCount(); 10603 vcount += geo.getValidVertexCount(); 10604 geoOffset[i] = offset; 10605 offset += geo.stride() * compileVcount[i]; 10606 vformat = geo.getVertexFormat(); 10607 } 10608 createGeometryArrayData(vcount, vformat); 10609 10610 // Assign the initial and valid fields 10611 validVertexCount = vcount; 10612 initialVertexIndex = 0; 10613 10614 mergeGeometryArrays(curList); 10615 10616 } 10617 10618 /* 10619 // Ununsed 10620 int getVertexCount(int index) { 10621 return compileVcount[index]; 10622 } 10623 10624 10625 int getValidVertexCount(int index) { 10626 return compileVcount[index]; 10627 } 10628 10629 10630 int getInitialVertexIndex(int index) { 10631 return 0; 10632 } 10633 */ 10634 mergeGeometryArrays(ArrayList list)10635 void mergeGeometryArrays(ArrayList list) { 10636 float[] curVertexData; 10637 int length, srcOffset; 10638 int curOffset = 0; 10639 // We only merge if the texCoordSetCount is 1 and there are no 10640 // vertex attrs 10641 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { 10642 texCoordSetCount = 1; 10643 texCoordSetMap = new int[1]; 10644 texCoordSetMap[0] = 1; 10645 } 10646 for (int i = 0; i < list.size(); i++) { 10647 GeometryArrayRetained geo = (GeometryArrayRetained)list.get(i); 10648 // Take into account the validVertexCount and initialVertexIndex 10649 curVertexData = geo.vertexData; 10650 length = geo.validVertexCount * stride; 10651 srcOffset = geo.initialVertexIndex * stride; 10652 System.arraycopy(curVertexData, srcOffset, this.vertexData, curOffset, 10653 length); 10654 curOffset += length; 10655 10656 // assign geoBounds 10657 geoBounds.combine(geo.geoBounds); 10658 10659 } 10660 this.centroid.set(geoBounds.getCenter()); 10661 } 10662 isMergeable()10663 boolean isMergeable() { 10664 10665 // For now, turn off by ref geometry 10666 if ((vertexFormat & GeometryArray.BY_REFERENCE) != 0) 10667 return false; 10668 10669 if (!isStatic()) 10670 return false; 10671 10672 // If there is more than one set of texture coordinate set defined 10673 // then don't merge geometry (we avoid dealing with texCoordSetMap 10674 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0 && 10675 (texCoordSetCount > 1 || 10676 texCoordSetMap != null && texCoordSetMap.length > 1)) { 10677 return false; 10678 } 10679 10680 // We will avoid merging geometry if there are any vertex attributes. 10681 if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { 10682 return false; 10683 } 10684 10685 // If intersect is allowed turn off merging 10686 if (source.getCapability(Geometry.ALLOW_INTERSECT)) 10687 return false; 10688 10689 return true; 10690 } 10691 compile(CompileState compState)10692 void compile(CompileState compState) { 10693 super.compile(compState); 10694 10695 if ((vertexFormat & GeometryArray.NORMALS) != 0) { 10696 compState.needNormalsTransform = true; 10697 } 10698 } 10699 mergeTransform(TransformGroupRetained xform)10700 void mergeTransform(TransformGroupRetained xform) { 10701 if (geoBounds != null) { 10702 geoBounds.transform(xform.transform); 10703 } 10704 } 10705 10706 // This adds a MorphRetained to the list of users of this geometry addMorphUser(MorphRetained m)10707 void addMorphUser(MorphRetained m) { 10708 int index; 10709 ArrayList morphList; 10710 10711 if(morphUniverseList == null) { 10712 morphUniverseList = new ArrayList(1); 10713 morphUserLists = new ArrayList(1); 10714 } 10715 synchronized (morphUniverseList) { 10716 if (morphUniverseList.contains(m.universe)) { 10717 index = morphUniverseList.indexOf(m.universe); 10718 morphList = (ArrayList)morphUserLists.get(index); 10719 morphList.add(m); 10720 } else { 10721 morphUniverseList.add(m.universe); 10722 morphList = new ArrayList(5); 10723 morphList.add(m); 10724 morphUserLists.add(morphList); 10725 } 10726 } 10727 } 10728 10729 // This adds a MorphRetained to the list of users of this geometry removeMorphUser(MorphRetained m)10730 void removeMorphUser(MorphRetained m) { 10731 int index; 10732 ArrayList morphList; 10733 10734 if(morphUniverseList == null) 10735 return; 10736 10737 synchronized (morphUniverseList) { 10738 index = morphUniverseList.indexOf(m.universe); 10739 morphList = (ArrayList)morphUserLists.get(index); 10740 morphList.remove(morphList.indexOf(m)); 10741 if (morphList.size() == 0) { 10742 morphUserLists.remove(index); 10743 morphUniverseList.remove(index); 10744 } 10745 } 10746 } 10747 // Initialize mirror object when geometry is first setLived initMirrorGeometry()10748 void initMirrorGeometry() { 10749 geomLock.getLock(); 10750 if (this instanceof IndexedGeometryArrayRetained) { 10751 if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) { 10752 mirrorGeometry = 10753 ((IndexedGeometryArrayRetained)this).cloneNonIndexedGeometry(); 10754 } 10755 else { 10756 mirrorGeometry = null; 10757 } 10758 } 10759 geomLock.unLock(); 10760 10761 } 10762 10763 // Update Mirror Object in response to change in geometry updateMirrorGeometry()10764 void updateMirrorGeometry() { 10765 geomLock.getLock(); 10766 if (this instanceof IndexedGeometryArrayRetained) { 10767 if (mirrorGeometry != null) { 10768 mirrorGeometry = 10769 ((IndexedGeometryArrayRetained)this).cloneNonIndexedGeometry(); 10770 } 10771 } 10772 geomLock.unLock(); 10773 10774 } 10775 10776 10777 // Used by the picking intersect routines getVertexData(int i, Point3d pnts)10778 void getVertexData(int i, Point3d pnts) { 10779 int offset; 10780 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 10781 offset = stride * i + coordinateOffset; 10782 pnts.x = this.vertexData[offset]; 10783 pnts.y = this.vertexData[offset+1]; 10784 pnts.z = this.vertexData[offset+2]; 10785 return; 10786 } 10787 10788 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0 ) { 10789 if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { 10790 offset = stride * i + coordinateOffset; 10791 pnts.x = this.interLeavedVertexData[offset]; 10792 pnts.y = this.interLeavedVertexData[offset+1]; 10793 pnts.z = this.interLeavedVertexData[offset+2]; 10794 } 10795 else { 10796 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 10797 case GeometryArrayRetained.PF: 10798 offset = i*3; 10799 pnts.x = this.floatRefCoords[offset]; 10800 pnts.y = this.floatRefCoords[offset+1]; 10801 pnts.z = this.floatRefCoords[offset+2]; 10802 break; 10803 case GeometryArrayRetained.PD: 10804 offset = i*3; 10805 pnts.x = this.doubleRefCoords[offset]; 10806 pnts.y = this.doubleRefCoords[offset+1]; 10807 pnts.z = this.doubleRefCoords[offset+2]; 10808 break; 10809 case GeometryArrayRetained.P3F: 10810 pnts.x = this.p3fRefCoords[i].x; 10811 pnts.y = this.p3fRefCoords[i].y; 10812 pnts.z = this.p3fRefCoords[i].z; 10813 break; 10814 case GeometryArrayRetained.P3D: 10815 pnts.x = this.p3dRefCoords[i].x; 10816 pnts.y = this.p3dRefCoords[i].y; 10817 pnts.z = this.p3dRefCoords[i].z; 10818 break; 10819 } 10820 } 10821 }// end of non nio buffer 10822 else { // NIO BUFFER 10823 if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { 10824 offset = stride * i + coordinateOffset; 10825 pnts.x = this.interleavedFloatBufferImpl.get(offset); 10826 pnts.y = this.interleavedFloatBufferImpl.get(offset+1); 10827 pnts.z = this.interleavedFloatBufferImpl.get(offset+2); 10828 } 10829 else { 10830 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 10831 case GeometryArrayRetained.PF: 10832 offset = i*3; 10833 pnts.x = this.floatBufferRefCoords.get(offset); 10834 pnts.y = this.floatBufferRefCoords.get(offset+1); 10835 pnts.z = this.floatBufferRefCoords.get(offset+2); 10836 break; 10837 case GeometryArrayRetained.PD: 10838 offset = i*3; 10839 pnts.x = this.doubleBufferRefCoords.get(offset); 10840 pnts.y = this.doubleBufferRefCoords.get(offset+1); 10841 pnts.z = this.doubleBufferRefCoords.get(offset+2); 10842 break; 10843 } 10844 } 10845 } // end of nio buffer 10846 } 10847 getCrossValue(Point3d p1, Point3d p2, Vector3d value)10848 void getCrossValue(Point3d p1, Point3d p2, Vector3d value) { 10849 value.x += p1.y*p2.z - p1.z*p2.y; 10850 value.y += p2.x*p1.z - p2.z*p1.x; 10851 value.z += p1.x*p2.y - p1.y*p2.x; 10852 } 10853 10854 intersect(Transform3D thisLocalToVworld, Transform3D otherLocalToVworld, GeometryRetained geom)10855 boolean intersect(Transform3D thisLocalToVworld, 10856 Transform3D otherLocalToVworld, GeometryRetained geom) { 10857 10858 Transform3D t3d = new Transform3D(); 10859 boolean isIntersect = false; 10860 10861 if (geom instanceof GeometryArrayRetained ) { 10862 GeometryArrayRetained geomArray = (GeometryArrayRetained) geom; 10863 10864 if (geomArray.validVertexCount >= validVertexCount) { 10865 t3d.invert(otherLocalToVworld); 10866 t3d.mul(thisLocalToVworld); 10867 isIntersect = intersect(t3d, geom); 10868 } else { 10869 t3d.invert(thisLocalToVworld); 10870 t3d.mul(otherLocalToVworld); 10871 isIntersect = geomArray.intersect(t3d, this); 10872 } 10873 } else { 10874 t3d.invert(thisLocalToVworld); 10875 t3d.mul(otherLocalToVworld); 10876 isIntersect = geom.intersect(t3d, this); 10877 } 10878 return isIntersect; 10879 } 10880 getNumCoordCount()10881 int getNumCoordCount() { 10882 int count = 0; 10883 if ((vertexFormat & GeometryArray.COORDINATES) != 0){ 10884 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0){ 10885 count = vertexCount; 10886 return count; 10887 } 10888 10889 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 10890 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 10891 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 10892 case PF: 10893 count = floatRefCoords.length/3; 10894 break; 10895 case PD: 10896 count = doubleRefCoords.length/3; 10897 break; 10898 case P3F: 10899 count = p3fRefCoords.length; 10900 break; 10901 case P3D: 10902 count = p3dRefCoords.length; 10903 break; 10904 } 10905 } 10906 else { 10907 count = interLeavedVertexData.length/stride; 10908 } 10909 } 10910 else { // nio buffer 10911 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 10912 switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { 10913 case PF: 10914 count = floatBufferRefCoords.limit()/3; // XXXX: limit or capacity? 10915 break; 10916 case PD: 10917 count = doubleBufferRefCoords.limit()/3; 10918 break; 10919 } 10920 } 10921 else { 10922 count = interleavedFloatBufferImpl.limit()/stride; 10923 } 10924 } 10925 } 10926 return count; 10927 } 10928 getNumColorCount()10929 int getNumColorCount() { 10930 int count = 0; 10931 if ((vertexFormat & GeometryArray.COLOR) != 0){ 10932 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0){ 10933 count = vertexCount; 10934 return count; 10935 } 10936 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 10937 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 10938 switch ((vertexType & GeometryArrayRetained.COLOR_DEFINED)) { 10939 case CF: 10940 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10941 count = floatRefColors.length/3; 10942 } 10943 else if ((vertexFormat & GeometryArray.COLOR_4)== GeometryArray.COLOR_4){ 10944 count = floatRefColors.length/4; 10945 } 10946 break; 10947 case CUB: 10948 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10949 count = byteRefColors.length/3; 10950 } 10951 else if ((vertexFormat & GeometryArray.COLOR_4)== GeometryArray.COLOR_4){ 10952 count = byteRefColors.length/4; 10953 } 10954 break; 10955 case C3F: 10956 count = c3fRefColors.length; 10957 break; 10958 case C4F: 10959 count = c4fRefColors.length; 10960 break; 10961 case C3UB: 10962 count = c3bRefColors.length; 10963 break; 10964 case C4UB: 10965 count = c4bRefColors.length; 10966 break; 10967 } 10968 } 10969 else { 10970 count = interLeavedVertexData.length/stride; 10971 } 10972 } // end of non nio buffer 10973 else { 10974 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 10975 switch ((vertexType & GeometryArrayRetained.COLOR_DEFINED)) { 10976 case CF: 10977 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10978 count = floatBufferRefColors.limit()/3; 10979 } 10980 else if ((vertexFormat & GeometryArray.COLOR_4)== GeometryArray.COLOR_4){ 10981 count = floatBufferRefColors.limit()/4; 10982 } 10983 break; 10984 case CUB: 10985 if ((vertexFormat & GeometryArray.COLOR_4) == GeometryArray.COLOR_3) { 10986 count = byteBufferRefColors.limit()/3; 10987 } 10988 else if ((vertexFormat & GeometryArray.COLOR_4)== GeometryArray.COLOR_4){ 10989 count = byteBufferRefColors.limit()/4; 10990 } 10991 break; 10992 } 10993 } 10994 else { 10995 count = interleavedFloatBufferImpl.limit()/stride; 10996 } 10997 } // end of nio buffer 10998 } 10999 return count; 11000 } 11001 getNumNormalCount()11002 int getNumNormalCount() { 11003 int count = 0; 11004 if ((vertexFormat & GeometryArray.NORMALS) != 0){ 11005 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0){ 11006 count = vertexCount; 11007 return count; 11008 } 11009 11010 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 11011 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 11012 switch ((vertexType & NORMAL_DEFINED)) { 11013 case NF: 11014 count = floatRefNormals.length/3; 11015 break; 11016 case N3F: 11017 count = v3fRefNormals.length; 11018 break; 11019 } 11020 } 11021 else { 11022 count = interLeavedVertexData.length/stride; 11023 } 11024 } // end of non nio buffer 11025 else { 11026 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 11027 if ((vertexType & NORMAL_DEFINED) == NF ) { 11028 count = floatBufferRefNormals.limit()/3; 11029 } 11030 } 11031 else { 11032 count = interleavedFloatBufferImpl.limit()/stride; 11033 } 11034 } 11035 } 11036 return count; 11037 } 11038 getNumTexCoordCount(int i)11039 int getNumTexCoordCount(int i) { 11040 int count = 0; 11041 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0){ 11042 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0){ 11043 count = vertexCount; 11044 return count; 11045 } 11046 11047 if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { 11048 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 11049 switch ((vertexType & TEXCOORD_DEFINED)) { 11050 case TF: 11051 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { 11052 count = ((float[])refTexCoords[i]).length/2; 11053 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 11054 count = ((float[])refTexCoords[i]).length/3; 11055 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 11056 count = ((float[])refTexCoords[i]).length/4; 11057 } 11058 11059 break; 11060 case T2F: 11061 count = ((TexCoord2f[])refTexCoords[i]).length; 11062 break; 11063 case T3F: 11064 count = ((TexCoord3f[])refTexCoords[i]).length; 11065 } 11066 } 11067 else { 11068 count = interLeavedVertexData.length/stride; 11069 } 11070 } 11071 else { // nio buffer 11072 if ((vertexFormat & GeometryArray.INTERLEAVED) == 0){ 11073 if ((vertexType & TEXCOORD_DEFINED) == TF) { 11074 FloatBufferWrapper texBuffer = (FloatBufferWrapper)(((J3DBuffer) refTexCoordsBuffer[i]).getBufferImpl()); 11075 if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { 11076 count = texBuffer.limit()/2; 11077 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { 11078 count = texBuffer.limit()/3; 11079 } else if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { 11080 count = texBuffer.limit()/4; 11081 } 11082 } 11083 } 11084 else { 11085 count = interleavedFloatBufferImpl.limit()/stride; 11086 } 11087 } 11088 } 11089 return count; 11090 } 11091 11092 // NOTE: we don't need a getNumVertexAttrCount method, since getNum*Count 11093 // is only called by Morph, which doesn't support vertex attrs 11094 11095 11096 // Found the min distance from center to the point/line/tri/quad 11097 // form by dist[] computeMinDistance(Point3d coordinates[], Point3d center, Vector3d normal, double dist[], Point3d iPnt)11098 void computeMinDistance(Point3d coordinates[], Point3d center, 11099 Vector3d normal, 11100 double dist[], Point3d iPnt) { 11101 double x, y, z; 11102 int i, j; 11103 11104 if (coordinates.length == 1) { 11105 // a point 11106 iPnt.x = coordinates[0].x; 11107 iPnt.y = coordinates[0].y; 11108 iPnt.z = coordinates[0].z; 11109 x = iPnt.x - center.x; 11110 y = iPnt.y - center.y; 11111 z = iPnt.z - center.z; 11112 dist[0] = Math.sqrt(x*x + y*y + z*z); 11113 return; 11114 } 11115 11116 11117 if (coordinates.length == 2) { 11118 // a line 11119 dist[0] = Math.sqrt(Distance.pointToSegment(center, 11120 coordinates[0], 11121 coordinates[1], 11122 iPnt, null)); 11123 return; 11124 } 11125 11126 double normalLen = 0; 11127 11128 if (normal == null) { 11129 Vector3d vec0 = new Vector3d(); 11130 Vector3d vec1 = new Vector3d(); 11131 normal = new Vector3d(); 11132 // compute plane normal for coordinates. 11133 for (i=0; i<coordinates.length-1;) { 11134 vec0.x = coordinates[i+1].x - coordinates[i].x; 11135 vec0.y = coordinates[i+1].y - coordinates[i].y; 11136 vec0.z = coordinates[i+1].z - coordinates[i++].z; 11137 if(vec0.length() > 0.0) 11138 break; 11139 } 11140 11141 for (j=i; j<coordinates.length-1; j++) { 11142 vec1.x = coordinates[j+1].x - coordinates[j].x; 11143 vec1.y = coordinates[j+1].y - coordinates[j].y; 11144 vec1.z = coordinates[j+1].z - coordinates[j].z; 11145 if(vec1.length() > 0.0) 11146 break; 11147 } 11148 11149 if (j == (coordinates.length-1)) { 11150 // Degenerate polygon, check with edge only 11151 normal = null; 11152 } else { 11153 normal.cross(vec0,vec1); 11154 } 11155 } 11156 11157 if (normal != null) { 11158 normalLen = normal.length(); 11159 if ( normalLen == 0.0) { 11160 // Degenerate polygon, check with edge only 11161 normal = null; 11162 } 11163 } 11164 11165 11166 if (coordinates.length == 3) { 11167 // a triangle 11168 if (normal != null) { 11169 double d = -(normal.x*coordinates[0].x + 11170 normal.y*coordinates[0].y + 11171 normal.z*coordinates[0].z); 11172 dist[0] = (normal.x*center.x + normal.y*center.y + 11173 normal.z*center.z + 11174 d)/normalLen; 11175 iPnt.x = center.x - dist[0]*normal.x/normalLen; 11176 iPnt.y = center.y - dist[0]*normal.y/normalLen; 11177 iPnt.z = center.z - dist[0]*normal.z/normalLen; 11178 11179 if (pointInTri(iPnt, coordinates[0], coordinates[1], 11180 coordinates[2], normal)) { 11181 return; 11182 } 11183 } 11184 11185 // checking point to line distance 11186 double minDist; 11187 Point3d minPnt = new Point3d(); 11188 11189 dist[0] = Distance.pointToSegment(center, coordinates[0], 11190 coordinates[1], iPnt, null); 11191 minDist = Distance.pointToSegment(center, coordinates[1], 11192 coordinates[2], minPnt, null); 11193 if (minDist < dist[0]) { 11194 dist[0] = minDist; 11195 iPnt.x = minPnt.x; 11196 iPnt.y = minPnt.y; 11197 iPnt.z = minPnt.z; 11198 } 11199 minDist = Distance.pointToSegment(center, coordinates[2], 11200 coordinates[0], minPnt, null); 11201 if (minDist < dist[0]) { 11202 dist[0] = minDist; 11203 iPnt.x = minPnt.x; 11204 iPnt.y = minPnt.y; 11205 iPnt.z = minPnt.z; 11206 } 11207 dist[0] = Math.sqrt(dist[0]); 11208 return; 11209 } 11210 11211 // a quad 11212 if (normal != null) { 11213 double d = -(normal.x*coordinates[0].x + 11214 normal.y*coordinates[0].y + 11215 normal.z*coordinates[0].z); 11216 dist[0] = (normal.x*center.x + normal.y*center.y + 11217 normal.z*center.z + 11218 d)/normalLen; 11219 iPnt.x = center.x - dist[0]*normal.x/normalLen; 11220 iPnt.y = center.y - dist[0]*normal.y/normalLen; 11221 iPnt.z = center.z - dist[0]*normal.z/normalLen; 11222 11223 if (pointInTri(iPnt, coordinates[0], coordinates[1], 11224 coordinates[2], normal) || 11225 pointInTri(iPnt, coordinates[1], coordinates[2], 11226 coordinates[3], normal)) { 11227 return; 11228 } 11229 } 11230 11231 // checking point to line distance 11232 double minDist; 11233 Point3d minPnt = new Point3d(); 11234 11235 dist[0] = Distance.pointToSegment(center, coordinates[0], 11236 coordinates[1], iPnt, null); 11237 minDist = Distance.pointToSegment(center, coordinates[1], 11238 coordinates[2], minPnt, null); 11239 if (minDist < dist[0]) { 11240 dist[0] = minDist; 11241 iPnt.x = minPnt.x; 11242 iPnt.y = minPnt.y; 11243 iPnt.z = minPnt.z; 11244 } 11245 minDist = Distance.pointToSegment(center, coordinates[2], 11246 coordinates[3], minPnt, null); 11247 if (minDist < dist[0]) { 11248 dist[0] = minDist; 11249 iPnt.x = minPnt.x; 11250 iPnt.y = minPnt.y; 11251 iPnt.z = minPnt.z; 11252 } 11253 11254 minDist = Distance.pointToSegment(center, coordinates[3], 11255 coordinates[0], minPnt, null); 11256 if (minDist < dist[0]) { 11257 dist[0] = minDist; 11258 iPnt.x = minPnt.x; 11259 iPnt.y = minPnt.y; 11260 iPnt.z = minPnt.z; 11261 } 11262 11263 dist[0] = Math.sqrt(dist[0]); 11264 } 11265 handleFrequencyChange(int bit)11266 void handleFrequencyChange(int bit) { 11267 int mask = 0; 11268 if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { 11269 if ((bit == GeometryArray.ALLOW_COORDINATE_WRITE) || 11270 (((vertexFormat & GeometryArray.COLOR) != 0) && 11271 bit == GeometryArray.ALLOW_COLOR_WRITE)|| 11272 (((vertexFormat & GeometryArray.NORMALS) != 0) && 11273 bit == GeometryArray.ALLOW_NORMAL_WRITE) || 11274 (((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) && 11275 bit == GeometryArray.ALLOW_TEXCOORD_WRITE) || 11276 (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) && 11277 bit == GeometryArray.ALLOW_VERTEX_ATTR_WRITE) || 11278 (bit == GeometryArray.ALLOW_COUNT_WRITE)) { 11279 mask = 1; 11280 } 11281 } 11282 else { 11283 if (bit == GeometryArray.ALLOW_REF_DATA_WRITE) 11284 mask = 1; 11285 } 11286 if (mask != 0) { 11287 setFrequencyChangeMask(bit, mask); 11288 } 11289 } 11290 getTexCoordType()11291 int getTexCoordType() { 11292 return texCoordType; 11293 } 11294 getVertexAttrType()11295 int getVertexAttrType() { 11296 return vertexAttrType; 11297 } 11298 11299 } 11300