4848import static com .jme3 .scene .plugins .gltf .GltfUtils .*;
4949import com .jme3 .texture .Texture ;
5050import com .jme3 .texture .Texture2D ;
51+ import com .jme3 .util .BufferInputStream ;
52+ import com .jme3 .util .BufferUtils ;
5153import com .jme3 .util .IntMap ;
5254import com .jme3 .util .mikktspace .MikktspaceTangentGenerator ;
5355import java .io .*;
5456import java .net .URLDecoder ;
5557import java .nio .Buffer ;
58+ import java .nio .ByteBuffer ;
5659import java .nio .FloatBuffer ;
5760import java .util .*;
5861import java .util .logging .Level ;
@@ -109,7 +112,6 @@ public Object load(AssetInfo assetInfo) throws IOException {
109112
110113 protected Object loadFromStream (AssetInfo assetInfo , InputStream stream ) throws IOException {
111114 try {
112- dataCache .clear ();
113115 info = assetInfo ;
114116 skinnedSpatials .clear ();
115117 rootNode = new Node ();
@@ -181,6 +183,27 @@ protected Object loadFromStream(AssetInfo assetInfo, InputStream stream) throws
181183 throw new AssetLoadException ("An error occurred loading " + assetInfo .getKey ().getName (), e );
182184 } finally {
183185 stream .close ();
186+ dataCache .clear ();
187+ skinBuffers .clear ();
188+ skinnedSpatials .clear ();
189+ info = null ;
190+ docRoot = null ;
191+ rootNode = null ;
192+ defaultMat = null ;
193+ accessors = null ;
194+ bufferViews = null ;
195+ buffers = null ;
196+ scenes = null ;
197+ nodes = null ;
198+ meshes = null ;
199+ materials = null ;
200+ textures = null ;
201+ images = null ;
202+ samplers = null ;
203+ animations = null ;
204+ skins = null ;
205+ cameras = null ;
206+ useNormalsFlag = false ;
184207 }
185208 }
186209
@@ -553,11 +576,15 @@ public Object readBuffer(Integer bufferViewIndex, int byteOffset, int count, Obj
553576 // Not sure it's useful for us, but I guess it's useful when you map data directly to the GPU.
554577 // int target = getAsInteger(bufferView, "target", 0);
555578
556- byte [] data = readData (bufferIndex );
579+ ByteBuffer data = readData (bufferIndex );
557580 data = customContentManager .readExtensionAndExtras ("bufferView" , bufferView , data );
558581
582+ if (!(data instanceof ByteBuffer )){
583+ throw new IOException ("Buffer data is not a NIO Buffer" );
584+ }
585+
559586 if (store == null ) {
560- store = new byte [ byteLength ] ;
587+ store = BufferUtils . createByteBuffer ( byteLength ) ;
561588 }
562589
563590 if (count == -1 ) {
@@ -569,14 +596,40 @@ public Object readBuffer(Integer bufferViewIndex, int byteOffset, int count, Obj
569596 return store ;
570597 }
571598
572- public byte [] readData (int bufferIndex ) throws IOException {
599+ public Buffer viewBuffer (Integer bufferViewIndex , int byteOffset , int count ,
600+ int numComponents , VertexBuffer .Format originalFormat , VertexBuffer .Format targetFormat ) throws IOException {
601+ JsonObject bufferView = bufferViews .get (bufferViewIndex ).getAsJsonObject ();
602+ Integer bufferIndex = getAsInteger (bufferView , "buffer" );
603+ assertNotNull (bufferIndex , "No buffer defined for bufferView " + bufferViewIndex );
604+ int bvByteOffset = getAsInteger (bufferView , "byteOffset" , 0 );
605+ Integer byteLength = getAsInteger (bufferView , "byteLength" );
606+ assertNotNull (byteLength , "No byte length defined for bufferView " + bufferViewIndex );
607+ int byteStride = getAsInteger (bufferView , "byteStride" , 0 );
608+
609+ ByteBuffer data = readData (bufferIndex );
610+ data = customContentManager .readExtensionAndExtras ("bufferView" , bufferView , data );
611+
612+ if (!(data instanceof ByteBuffer )){
613+ throw new IOException ("Buffer data is not a NIO Buffer" );
614+ }
615+
616+
617+ if (count == -1 ) {
618+ count = byteLength ;
619+ }
620+
621+ return GltfUtils .getBufferView (data , byteOffset + bvByteOffset , count , byteStride , numComponents , originalFormat , targetFormat );
622+
623+ }
624+
625+ public ByteBuffer readData (int bufferIndex ) throws IOException {
573626 assertNotNull (buffers , "No buffer defined" );
574627
575628 JsonObject buffer = buffers .get (bufferIndex ).getAsJsonObject ();
576629 String uri = getAsString (buffer , "uri" );
577630 Integer bufferLength = getAsInteger (buffer , "byteLength" );
578631 assertNotNull (bufferLength , "No byteLength defined for buffer " + bufferIndex );
579- byte [] data = (byte [] ) fetchFromCache ("buffers" , bufferIndex , Object .class );
632+ ByteBuffer data = (ByteBuffer ) fetchFromCache ("buffers" , bufferIndex , Object .class );
580633 if (data != null ) {
581634 return data ;
582635 }
@@ -588,12 +641,12 @@ public byte[] readData(int bufferIndex) throws IOException {
588641 return data ;
589642 }
590643
591- protected byte [] getBytes (int bufferIndex , String uri , Integer bufferLength ) throws IOException {
592- byte [] data ;
644+ protected ByteBuffer getBytes (int bufferIndex , String uri , Integer bufferLength ) throws IOException {
645+ ByteBuffer data ;
593646 if (uri != null ) {
594647 if (uri .startsWith ("data:" )) {
595648 // base 64 embed data
596- data = Base64 .getDecoder ().decode (uri .substring (uri .indexOf ("," ) + 1 ));
649+ data = BufferUtils . createByteBuffer ( Base64 .getDecoder ().decode (uri .substring (uri .indexOf ("," ) + 1 ) ));
597650 } else {
598651 // external file let's load it
599652 String decoded = decodeUri (uri );
@@ -603,11 +656,11 @@ protected byte[] getBytes(int bufferIndex, String uri, Integer bufferLength) thr
603656 }
604657
605658 BinDataKey key = new BinDataKey (info .getKey ().getFolder () + decoded );
606- InputStream input = (InputStream ) info .getManager ().loadAsset (key );
607- data = new byte [bufferLength ];
608- try (DataInputStream dataStream = new DataInputStream (input )) {
609- dataStream .readFully (data );
659+ try (InputStream input = (InputStream ) info .getManager ().loadAsset (key )){
660+ data = BufferUtils .createByteBuffer (bufferLength );
661+ GltfUtils .readToByteBuffer (input , data , bufferLength , -1 );
610662 }
663+
611664 }
612665 } else {
613666 // no URI, this should not happen in a gltf file, only in glb files.
@@ -784,19 +837,23 @@ public Texture2D readImage(int sourceIndex, boolean flip) throws IOException {
784837 if (uri == null ) {
785838 assertNotNull (bufferView , "Image " + sourceIndex + " should either have an uri or a bufferView" );
786839 assertNotNull (mimeType , "Image " + sourceIndex + " should have a mimeType" );
787- byte [] data = (byte []) readBuffer (bufferView , 0 , -1 , null , 1 , VertexBuffer .Format .Byte );
840+ ByteBuffer data = (ByteBuffer ) viewBuffer (bufferView , 0 , -1 , 1 , VertexBuffer .Format .Byte , VertexBuffer .Format .Byte );
841+
788842 String extension = mimeType .split ("/" )[1 ];
789843 TextureKey key = new TextureKey ("image" + sourceIndex + "." + extension , flip );
790- result = (Texture2D ) info .getManager ().loadAssetFromStream (key , new ByteArrayInputStream (data ));
791-
844+ try (BufferedInputStream bis = new BufferedInputStream (new BufferInputStream (data ))){
845+ result = (Texture2D ) info .getManager ().loadAssetFromStream (key , bis );
846+ }
792847 } else if (uri .startsWith ("data:" )) {
793848 // base64 encoded image
794849 String [] uriInfo = uri .split ("," );
795- byte [] data = Base64 .getDecoder ().decode (uriInfo [1 ]);
850+ ByteBuffer data = BufferUtils . createByteBuffer ( Base64 .getDecoder ().decode (uriInfo [1 ]) );
796851 String headerInfo = uriInfo [0 ].split (";" )[0 ];
797852 String extension = headerInfo .split ("/" )[1 ];
798853 TextureKey key = new TextureKey ("image" + sourceIndex + "." + extension , flip );
799- result = (Texture2D ) info .getManager ().loadAssetFromStream (key , new ByteArrayInputStream (data ));
854+ try (BufferedInputStream bis = new BufferedInputStream (new BufferInputStream (data ))){
855+ result = (Texture2D ) info .getManager ().loadAssetFromStream (key , bis );
856+ }
800857 } else {
801858 // external file image
802859 String decoded = decodeUri (uri );
@@ -1338,13 +1395,16 @@ public VertexBuffer populate(Integer bufferViewIndex, int componentType, String
13381395 }
13391396 int numComponents = getNumberOfComponents (type );
13401397
1341- Buffer buff = VertexBuffer .createBuffer (format , numComponents , count );
13421398 int bufferSize = numComponents * count ;
1399+ Buffer buff ;
13431400 if (bufferViewIndex == null ) {
1401+ buff = VertexBuffer .createBuffer (format , numComponents , count );
13441402 // no referenced buffer, specs says to pad the buffer with zeros.
13451403 padBuffer (buff , bufferSize );
13461404 } else {
1347- readBuffer (bufferViewIndex , byteOffset , count , buff , numComponents , originalFormat );
1405+ // buff = VertexBuffer.createBuffer(format, numComponents, count);
1406+ // buff = (Buffer) readBuffer(bufferViewIndex, byteOffset, count, buff, numComponents, originalFormat);
1407+ buff = (Buffer ) viewBuffer (bufferViewIndex , byteOffset , count , numComponents , originalFormat , format );
13481408 }
13491409
13501410 if (bufferType == VertexBuffer .Type .Index ) {
0 commit comments