LapisSea

Untitled

May 26th, 2018
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.34 KB | None | 0 0
  1. package com.lapissea.vulkanimpl.util;
  2.  
  3. import com.lapissea.datamanager.IDataManager;
  4. import com.lapissea.util.LogUtil;
  5. import com.lapissea.vulkanimpl.VkGpu;
  6. import com.lapissea.vulkanimpl.renderer.assets.ResourceManager;
  7. import com.lapissea.vulkanimpl.renderer.model.VkMaterial;
  8. import com.lapissea.vulkanimpl.renderer.model.VkModel;
  9. import com.lapissea.vulkanimpl.renderer.model.VkModelBuilder;
  10. import com.lapissea.vulkanimpl.util.types.VkTexture;
  11. import gnu.trove.map.hash.TLongObjectHashMap;
  12. import org.lwjgl.PointerBuffer;
  13. import org.lwjgl.assimp.*;
  14. import org.lwjgl.system.MemoryStack;
  15.  
  16. import java.io.File;
  17. import java.io.IOException;
  18. import java.nio.ByteBuffer;
  19. import java.nio.ByteOrder;
  20. import java.nio.IntBuffer;
  21. import java.nio.channels.FileChannel;
  22. import java.util.ArrayList;
  23. import java.util.List;
  24. import java.util.Objects;
  25. import java.util.function.IntFunction;
  26.  
  27. import static com.lapissea.datamanager.IDataManager.Mode.*;
  28. import static org.lwjgl.assimp.Assimp.*;
  29. import static org.lwjgl.system.MemoryStack.*;
  30. import static org.lwjgl.system.MemoryUtil.*;
  31. import static org.lwjgl.vulkan.VK10.*;
  32.  
  33. public class ModelLoader{
  34.    
  35.     public static List<VkModel> load(VkGpuCtx gpuCtx, IDataManager source, String path, ResourceManager<VkTexture> textures){
  36. //      File cacheFile=new File(".cache/rawModel", path+".zip");
  37. //      return FileChageDetector.getInfo(new File(path)).getChangeTime() >= FileChageDetector.getInfo(cacheFile).getChangeTime()?parseModel(gpuCtx.getGpu(), path, cacheFile, source):readCached(gpuCtx.getGpu(), cacheFile);
  38.         return parseModel(gpuCtx.getGpu(), path, source, textures);
  39.     }
  40.    
  41.     private static AIScene loadScene(String path, IDataManager source, int flags){
  42.         try(MemoryStack stack=MemoryStack.stackPush()){
  43.            
  44.             var ioSystem=AIFileIO.callocStack();
  45.            
  46.             TLongObjectHashMap<FileChannel> open=new TLongObjectHashMap<>(2);
  47.            
  48.             ioSystem
  49.                 .OpenProc((pFileIO, fileNameP, openModeP)->{
  50.                    
  51.                     String fileName=stack.pointers(fileNameP).getStringUTF8();
  52.                     String openMode=stack.pointers(openModeP).getStringUTF8();
  53.                    
  54.                     FileChannel channel=source.getRandomAccess(fileName, READ_ONLY);
  55.                     if(channel==null) return NULL;
  56.                    
  57.                     long   fileSize=source.getSize(fileName);
  58.                     long[] pos     ={0};
  59.                    
  60.                     AIFileReadProcI read=(filePtr, bufferPtr, size, count)->{
  61.                        
  62.                         long remaining=fileSize-pos[0];
  63.                        
  64.                         try{
  65.                             channel.read(memByteBuffer(bufferPtr, (int)count));
  66.                         }catch(IOException e){
  67.                             e.printStackTrace();
  68.                             System.exit(0);//TODO properly handle
  69.                         }
  70.                        
  71.                         return remaining;
  72.                     };
  73.                    
  74.                     AIFileSeekI seek=(pFile, offset, origin)->{
  75.                         pos[0]=origin+offset;
  76.                         return pos[0]==fileSize?0:1;
  77.                     };
  78.                     long pfil=AIFile.callocStack(stack)
  79.                                     .FileSizeProc(pFile->fileSize)
  80.                                     .ReadProc(read)
  81.                                     .SeekProc(seek)
  82.                                     .address();
  83.                    
  84.                     open.put(pfil, channel);
  85.                     return pfil;
  86.                 })
  87.                 .CloseProc((pFileIO, pFile)->{
  88.                     try{
  89.                         open.remove(pFile).close();
  90.                     }catch(IOException ignored){}
  91.                 });
  92.            
  93.             return Assimp.aiImportFileEx(path, flags, ioSystem);
  94.         }catch(Throwable th){
  95.             return null;
  96.         }
  97.     }
  98.    
  99.     private static List<VkModel> parseModel(VkGpu gpu, String path, IDataManager source, ResourceManager<VkTexture> textures){
  100.         LogUtil.println("parseModel", path);
  101.        
  102.         int flags=
  103.             aiProcess_FlipUVs|
  104.             aiProcess_Triangulate|
  105.             aiProcess_FlipWindingOrder|
  106.            
  107.             aiProcess_ImproveCacheLocality|
  108.             aiProcess_RemoveRedundantMaterials|
  109.             aiProcess_FindInstances;
  110.        
  111.         AIScene scene=loadScene(path, source, flags);
  112.         Objects.requireNonNull(scene);
  113.        
  114.         String modelRoot=new File(path).getParent();
  115.        
  116.         List<VkMaterial> mats=new ArrayList<>(scene.mNumMaterials());
  117.        
  118.         for(int i1=0;i1<scene.mNumMaterials();i1++){
  119.             int i=i1;
  120.             IntFunction<String> getTexture=type->{
  121.                 String ps;
  122.                
  123.                 try(MemoryStack stack=stackPush()){
  124.                    
  125.                     var m=AIMaterial.create(scene.mMaterials().get(i));
  126.                     var p=AIString.callocStack();
  127.                    
  128.                     synchronized(mats){
  129.                         Assimp.aiGetMaterialTexture(m, type, 0, p, (IntBuffer)null, null, null, null, null, null);
  130.                     }
  131.                    
  132.                     ps=p.dataString();
  133.                 }
  134.                
  135. //              if(!ps.isEmpty()) async(()->textures.getByName(modelRoot+"/"+ps));
  136.                 return ps.isEmpty()?ps:modelRoot+"/"+ps;
  137.             };
  138.            
  139.             mats.add(new VkMaterial(getTexture.apply(aiTextureType_DIFFUSE), getTexture.apply(aiTextureType_HEIGHT)));
  140.         }
  141.        
  142.         PointerBuffer meshes=scene.mMeshes();
  143.         Objects.requireNonNull(meshes);
  144.        
  145.         int           count =0;
  146.         List<VkModel> result=new ArrayList<>();
  147.        
  148.         for(int i2=0, j2=scene.mNumMeshes();i2<j2;i2++){
  149.            
  150.             AIMesh mesh=AIMesh.create(meshes.get(i2));
  151.            
  152.             AIFace.Buffer fa=mesh.mFaces();
  153.            
  154.             AIVector3D.Buffer vt=mesh.mVertices();
  155.             AIVector3D.Buffer nr=mesh.mNormals();
  156.             AIVector3D.Buffer uv=mesh.mTextureCoords(0);
  157.            
  158.             VkModelBuilder modelBuilder=new VkModelBuilder(VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT, VK_FORMAT_R32G32_SFLOAT);
  159.            
  160.             for(int i1=0;i1<vt.limit();i1++){
  161.                 modelBuilder.put3F(vt.position(i1).x(), vt.y(), vt.z());
  162.                
  163.                 if(nr!=null) modelBuilder.put3F(nr.position(i1).x(), nr.y(), nr.z());
  164.                 else modelBuilder.put3F(0, 0, 0);
  165.                
  166.                 if(uv!=null) modelBuilder.put2F(uv.position(i1).x(), uv.y());
  167.                 else modelBuilder.put2F(0, 0);
  168.                
  169.                 modelBuilder.next();
  170.             }
  171.            
  172.             int     idCheck   =0;
  173.             boolean continuous=true;
  174.            
  175.             for(int i=0;i<fa.limit();i++){
  176.                 fa.position(i);
  177.                 var ib=fa.mIndices();
  178.                
  179.                 for(int i1=0;i1<fa.mNumIndices();i1++){
  180.                     var id=ib.get(i1);
  181.                    
  182.                     if(continuous){
  183.                         if(idCheck++!=id){
  184.                             continuous=false;
  185.                         }
  186.                     }
  187.                     modelBuilder.addIndices(id);
  188.                 }
  189.             }
  190. //          LogUtil.println(continuous);
  191.             if(continuous) modelBuilder.clearIndex();
  192.            
  193.             int indexCount=modelBuilder.indexCount();
  194.             int size      =modelBuilder.totalSize();
  195.            
  196.             if(size==0) continue;
  197.            
  198.             byte[] mem=modelBuilder.writeAll(ByteBuffer.allocate(size).order(ByteOrder.nativeOrder())).array();
  199.             modelBuilder.clearAll();
  200.            
  201.             VkModel model=gpu.upload(bb->bb.put(mem), modelBuilder.format, size, indexCount);
  202.             model.material=mats.get(mesh.mMaterialIndex());
  203.             result.add(model);
  204.         }
  205.        
  206.         Assimp.aiFreeScene(scene);
  207.        
  208.         return result;
  209.        
  210.     }
  211.    
  212. }
Add Comment
Please, Sign In to add comment