Помогите с УФ на моем obj загрузчике на андроид - PullRequest
0 голосов
/ 30 декабря 2010

Я пытаюсь сделать свою первую игру для Android, и для этого я создал загрузчик OBJ, который берет идентификатор ресурса и использует InputStream, возвращенный Context.getResources (). OpenRawResource ().

Iудалось прочитать информацию о вершине и информацию о лице, и я могу успешно загрузить сетку без каких-либо текстур.

Видите, проблема в том, что текстуры не отображаются правильно.Мне удалось прочитать информацию из файла, поместив все числа после 'vt' в массив, а также индексы в f после первого '/' (то есть 'f 1/1 ...')

Я не совсем уверен, что я должен делать с числами, хотя ... если я просто помещу все в байтовый буфер и продолжу, как обычно, как я узнал из этих двух уроков ( jayway , и nehe порты) все равно получится не так.

Я думаю, что информация 'vt' в файле не в порядке (отсюда необходимость '/ x' в 'f 'data), и я должен как-то привести его в порядок перед созданием байтового буфера из массива .... Я не знаю, как это сделать: (

Поэтому я спрашиваю, может кто-нибудь предложитьмне немного помочь, пожалуйста? Я знаю, что есть другие загрузчики obj в Интернете, но я уже сделал этот, и я знаю, как он работает, не только это, но и лучший опыт обучения для меня.

Воткод, который я использую:

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Vector;

import android.content.Context;
import android.util.Log;
import com.snakeinalake.catchthemoney.Mesh.CMeshInfo;

public class CMeshParserOBJ extends CMeshParser{

 public CMeshParserOBJ(){
  type = "OBJ";  
 }

 @Override
 public CMeshInfo loadMesh(Context context, int FileID){
  CMeshInfo ret = new CMeshInfo(type);

  String buildWord = "";
  int data;
  int found = -1;

  Vector<Float> vert = new Vector<Float>();
  Vector<Float> uv = new Vector<Float>();
  Vector<Short> ind = new Vector<Short>();
  Vector<Short> map = new Vector<Short>();

  InputStream is = context.getResources().openRawResource(FileID);
  InputStreamReader rd = new InputStreamReader(is);

  try {
   data = rd.read();
   while(data!=-1){ 
    char c = (char)data;

     if(found == -1){
      if(c == 'v'){    //found vertex data
       data = rd.read();
        if((char)data == ' '){
         found = 1;
        }else if((char)data == 't'){ //found uv map data
         data = rd.read();
         if((char)data == ' '){
          found = 3;
         }
        }else{
         found = -1;        
        }
      }else if(c == 'f'){   //found index data (faces)
       data = rd.read();
       if((char)data == ' '){
        found = 2;
       }else{
        found = -1;        
       }
      }else{
       found = -1;       
      }
     }

     if(found == 1){
      float x = 0,y = 0,z = 0;     
      for(int repeat = 0; repeat<3; repeat++){
       buildWord="";
       do{
        data = rd.read();
        c = (char)data;    
        buildWord+=c;
       }while((char)data!=' ' && (char)data!='\n');
       if(repeat==0)
        x = Float.parseFloat(buildWord.trim());
       else if(repeat==1)
        y = Float.parseFloat(buildWord.trim());
       else if(repeat==2)
        z = Float.parseFloat(buildWord.trim());
      }
      vert.add(x);
      vert.add(y);
      vert.add(z);
      found = -1;
     }

     if(found == 2){
      short v1 = 0, v2 = 0, v3 = 0;
      short map1 = 0, map2 = 0, map3 = 0;
      boolean uvdata = false;
      for(int repeat = 0; repeat<3; repeat++){
       buildWord="";
       do{
        data = rd.read();
        if(!uvdata && (char)data == '/'){
         uvdata = true;        
        }else{
         c = (char)data;    
         buildWord+=c;
        }
       }while((char)data!=' ' && (char)data!='\n' && (char)data!='/');
       if(repeat==0){
        v1 = Short.parseShort(buildWord.trim());
       }else if(repeat==1){
        v2 = Short.parseShort(buildWord.trim());
       }else if(repeat==2){
        v3 = Short.parseShort(buildWord.trim());
       }

       if(uvdata){
        uvdata = false;
        buildWord = "";
        do{
         data = rd.read();
         c = (char)data;    
         buildWord+=c;
         if(!uvdata && (char)data == '/'){
          uvdata = true;        
         }
        }while((char)data!=' ' && (char)data!='\n');
        if(repeat == 0)
         map1 = Short.parseShort(buildWord.trim());
        else if(repeat == 1)
         map2 = Short.parseShort(buildWord.trim());
        else if(repeat == 2)
         map3 = Short.parseShort(buildWord.trim());
        else{
         map1 = 0; map2  = 0; map3 = 0;     
        }
       }
      }       
      ind.add(v1);
      ind.add(v2);
      ind.add(v3);

      map.add(map1);
      map.add(map2);
      map.add(map3);
      found = -1;
     }
     if(found == 3){
      float uvx = 0, uvy = 0;     
      for(int repeat = 0; repeat<2; repeat++){
       buildWord="";
       do{
        data = rd.read();
        c = (char)data;    
        buildWord+=c;
       }while((char)data!=' ' && (char)data!='\n');
       if(repeat==0)
        uvx = Float.parseFloat(buildWord.trim());
       else if(repeat==1)
        uvy = Float.parseFloat(buildWord.trim());
      }
      uv.add(uvx);
      uv.add(uvy);
      found = -1;
     }

    data = rd.read();
   }
   rd.close();

  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }


  ret.vertices = new float[vert.size()];
  for(int i=0; i<ret.vertices.length; i++){
   ret.vertices[i] = vert.get(i);
   Log.d("CATCH", Float.toString(ret.vertices[i]));
  }

  ret.uvMappings = new short[map.size()];
  for(int i=0; i<ret.uvMappings.length; i++){
   ret.uvMappings[i] = (short) (map.get(i)-1);
   Log.d("CATCH", Float.toString(ret.uvMappings[i]));
  }

  ret.uvtex = new float[uv.size()];
  for(int i=0; i<ret.uvtex.length; i++){
   ret.uvtex[i] = uv.get(i);
   Log.d("CATCH", Float.toString(ret.uvtex[i]));
  }

  ret.indices = new short[ind.size()];
  for(int i=0; i<ret.indices.length; i++){
   ret.indices[i] = (short) (ind.get(i)-1);
  }

  ret.MapUVCoordinates();
  ret.fillBuffers();

  return ret;
 }}

Метод 'ret.MapUVCoordiantes 'не работает, это была просто моя попытка заказать их самому ... Я не собираюсь публиковать это, потому что он просто ничего не делает.Метод ret.fullBuffers представлен ниже.Он просто создает байтовые буферы из массивов:

    public void fillBuffers(){
  ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
  ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
  ByteBuffer ubb = ByteBuffer.allocateDirect(uvtex.length * 4);

  Log.d("CMeshInfo::fillBuffers", Float.toString(vertices.length * 4));
  Log.d("CMeshInfo::fillBuffers", Float.toString((indices.length * 2)));
  Log.d("CMeshInfo::fillBuffers", Float.toString(uvtex.length * 4));


  vbb.order(ByteOrder.nativeOrder()); //Vertices
  ubb.order(ByteOrder.nativeOrder()); //UV coordinates
  ibb.order(ByteOrder.nativeOrder()); //Indices

  vertBuff = vbb.asFloatBuffer();
  uvBuff = ubb.asFloatBuffer();
  IndBuff = ibb.asShortBuffer();

  vertBuff.put(vertices);
  uvBuff.put(uvtex);
  IndBuff.put(indices);

  vertBuff.position(0);
  uvBuff.position(0);
  IndBuff.position(0);
 }

1 Ответ

1 голос
/ 30 декабря 2010

Если я правильно помню, эти числа являются индексами в массиве вершин.

...