LoadObj.inc
上传用户:yj_qiu
上传日期:2022-08-08
资源大小:23636k
文件大小:9k
源码类别:

游戏引擎

开发平台:

Delphi

  1. const                                    
  2.   cfeFileNotFound = 1; cfeFileCorrupt = 2;
  3. type
  4.   CFFace = array of record
  5.     V, N, T: Word;
  6.   end;
  7. var
  8.   FData: array of array[0..2] of record
  9.     V, N, T, M: Integer;
  10.   end;
  11. //  VertexData: array of Single;
  12.   VData, NData, TData: array of TVector3s;
  13.   MData: array of record
  14.     Name: string[40];
  15.     Diffuse, Specular: TVector3s;
  16.   end;
  17. function PosEx(const substr : AnsiString; const s : AnsiString; const start: Integer ) : Integer ;
  18. type StrRec = record allocSiz, refCnt, length: Longint; end;
  19. const skew = sizeof(StrRec);
  20. asm
  21. {     ->EAX     Pointer to substr               }
  22. {       EDX     Pointer to string               }
  23. {       ECX     Pointer to start      //cs      }
  24. {     <-EAX     Position of substr in s or 0    }
  25.         TEST    EAX,EAX
  26.         JE      @@noWork
  27.         TEST    EDX,EDX
  28.         JE      @@stringEmpty
  29.         TEST    ECX,ECX           //cs
  30.         JE      @@stringEmpty     //cs
  31.         PUSH    EBX
  32.         PUSH    ESI
  33.         PUSH    EDI
  34.         MOV     ESI,EAX                         { Point ESI to  }
  35.         MOV     EDI,EDX                         { Point EDI to  }
  36.         MOV     EBX,ECX        //cs save start
  37.         MOV     ECX,[EDI-skew].StrRec.length    { ECX =    }
  38.         PUSH    EDI                             { remember s position to calculate index }
  39.         CMP     EBX,ECX        //cs
  40.         JG      @@fail         //cs
  41.         MOV     EDX,[ESI-skew].StrRec.length    { EDX = bstr)          }
  42.         DEC     EDX                             { EDX = Length(substr) -   }
  43.         JS      @@fail                          { < 0 ? return             }
  44.         MOV     AL,[ESI]                        { AL = first char of       }
  45.         INC     ESI                             { Point ESI to 2'nd char of substr }
  46.         SUB     ECX,EDX                         { #positions in s to look  }
  47.                                                 { = Length(s) - Length(substr) + 1      }
  48.         JLE     @@fail
  49.         DEC     EBX       //cs
  50.         SUB     ECX,EBX   //cs
  51.         JLE     @@fail    //cs
  52.         ADD     EDI,EBX   //cs
  53. @@loop:
  54.         REPNE   SCASB
  55.         JNE     @@fail
  56.         MOV     EBX,ECX                         { save outer loop                }
  57.         PUSH    ESI                             { save outer loop substr pointer }
  58.         PUSH    EDI                             { save outer loop s              }
  59.         MOV     ECX,EDX
  60.         REPE    CMPSB
  61.         POP     EDI                             { restore outer loop s pointer      }
  62.         POP     ESI                             { restore outer loop substr pointer }
  63.         JE      @@found
  64.         MOV     ECX,EBX                         { restore outer loop nter    }
  65.         JMP     @@loop
  66. @@fail:
  67.         POP     EDX                             { get rid of saved s nter    }
  68.         XOR     EAX,EAX
  69.         JMP     @@exit
  70. @@stringEmpty:
  71.         XOR     EAX,EAX
  72.         JMP     @@noWork
  73. @@found:
  74.         POP     EDX                             { restore pointer to first char of s    }
  75.         MOV     EAX,EDI                         { EDI points of char after match        }
  76.         SUB     EAX,EDX                         { the difference is the correct index   }
  77. @@exit:
  78.         POP     EDI
  79.         POP     ESI
  80.         POP     EBX
  81. @@noWork:
  82. end;
  83. function GetCoords(S : string) : TVector3s;
  84. var P, P2 : Integer;
  85. begin
  86.   S := Trim(Copy(S, 3, Length(S)));
  87.   P := Pos(' ', S); P2 := PosEx(' ', S, P+1);
  88.   S := StringReplace(S, '.', DecimalSeparator, [rfReplaceAll]);
  89.   Result.X := StrToFloat(Copy(S, 1, P-1));
  90.   if P2 = 0 then begin
  91.     Result.Y := StrToFloat(Copy(S, P+1, Length(S)));
  92.     Result.Z := 0;
  93.   end else begin
  94.     Result.Y := StrToFloat(Copy(S, P+1, P2-P-1));
  95.     Result.Z := StrToFloat(Copy(S, P2+1, Length(S)));
  96.   end;  
  97. end;
  98. procedure LoadMaterials(S: string);
  99. var MF: Text; FileDir: TFileName;
  100. begin
  101.   FileDir := ExtractFileDir(Filename);
  102.   if (FileDir <> '') and (FileDir[Length(FileDir)] <> '') then FileDir := FileDir + '';
  103.   S2 := FileDir + Copy(Trim(S), Pos(' ', S)+1, Length(S));
  104.   if not FileExists(S2) then Exit;
  105.   AssignFile(MF, S2); Reset(MF);
  106.   while not EOF(MF) do begin
  107.     Readln(MF, S2); S2 := Trim(S2); S2 := Uppercase(S2);
  108.     if Copy(S2, 1, 6) = 'NEWMTL' then begin
  109.       Inc(MCount); SetLength(MData, MCount);
  110.       MData[MCount-1].Name := Copy(S2, Pos(' ', S2)+1, Length(S2));
  111.       if MData[MCount-1].Name = 'DEFAULT' then CurMaterial := MCount - 1;
  112.     end;
  113.     if Copy(S2, 1, 6) = 'MAP_KD' then TextureFileName := FileDir + Copy(S2, Pos(' ', S2)+1, Length(S2));
  114.     if Copy(S2, 1, 2) = 'KD' then MData[MCount-1].Diffuse := GetCoords(S2);
  115.     if Copy(S2, 1, 2) = 'KS' then MData[MCount-1].Specular := GetCoords(S2);
  116.   end;
  117.   CloseFile(MF);
  118. end;
  119. procedure ReadVertexData(S : string);
  120. var C : TVector3s; 
  121. begin
  122.   case S[2] of
  123.     ' ': begin
  124.       C := GetCoords(S);
  125.       Inc(VCount);
  126.       if Length(VData) < VCount then SetLength(VData, Length(VData) + ImportCapacityStep);
  127.       VData[VCount-1] := C;
  128.     end;
  129.     'N': begin
  130.       C := GetCoords(S);
  131.       Inc(NCount);
  132.       if Length(NData) < NCount then SetLength(NData, Length(NData) + ImportCapacityStep);
  133.       NData[NCount-1] := C;
  134.     end;
  135.     'T': begin
  136.       C := GetCoords(S);
  137.       Inc(TCount);
  138.       if Length(TData) < TCount then SetLength(TData, Length(TData) + ImportCapacityStep);
  139.       TData[TCount-1] := C;
  140.       TData[TCount-1].Y := 1-TData[TCount-1].Y;
  141.     end;
  142.   end;
  143. end;
  144. procedure ReadFaceData(S : string);
  145. var P, P3 : Integer; F : CFFace; FVCount: Word; I1, I2: Integer;
  146. begin
  147.   P := Pos(' ', S); S := Trim(Copy(S, P+1, Length(S)));
  148.   Inc(FCount);
  149.   if Length(FData) < FCount then SetLength(FData, Length(FData) + ImportCapacityStep);
  150.   FVCount := 0;                  //   f 22 3/4 12/33/44 33//66 77/22/
  151.   while (Length(S) > 0) do begin
  152.     Inc(FVCount);
  153.     if Length(F) < FVCount then SetLength(F, Length(F) + MaxI(1, ImportCapacityStep shr 3));
  154.     F[FVCount-1].N := 0; F[FVCount-1].T := 0;
  155.     P3 := Pos(' ', S);
  156.     if P3 = 0 then P3 := Length(S)+1;
  157.     S2 := Copy(S, 1, P3-1);            // 12/66/77
  158.     if S2[Length(S2)] = '/' then S2 := Copy(S2, 1, Length(S2)-1);
  159.     P := Pos('/', S2);
  160.     if P > 0 then F[FVCount-1].V := StrToInt(Copy(S2, 1, P-1))-1 else begin
  161.       F[FVCount-1].V := StrToInt(Copy(S2, 1, P3-1))-1;
  162.       S := Copy(S, P3+1, Length(S));
  163.       Continue;
  164.     end;
  165.     S2 := Copy(S2, P+1, Length(S2));
  166.     P := Pos('/', S2);
  167.     if P > 0 then F[FVcount-1].T := StrToIntDef(Copy(S2, 1, P-1), 1)-1 else begin
  168.       F[FVCount-1].T := StrToInt(Copy(S2, 1, P3-1))-1;
  169.       S := Copy(S, P3+1, Length(S));
  170.       Continue;
  171.     end;
  172.     S2 := Copy(S2, P+1, Length(S2));
  173.     P := Pos('/', S2);
  174.     if P > 0 then F[FVcount-1].N := StrToIntDef(Copy(S2, 1, P-1), 1)-1 else F[FVCount-1].N := StrToInt(Copy(S2, 1, P3-1))-1;
  175.     S := Copy(S, P3+1, Length(S));
  176.   end;
  177.   I1 := 1; I2 := 2;
  178.   FData[(FCount-1)][0].V := F[0].V;
  179.   FData[(FCount-1)][I1].V := F[1].V;
  180.   FData[(FCount-1)][I2].V := F[2].V;
  181.   FData[(FCount-1)][0].N := F[0].N;
  182.   FData[(FCount-1)][I1].N := F[1].N;
  183.   FData[(FCount-1)][I2].N := F[2].N;
  184.   FData[(FCount-1)][0].T := F[0].T;
  185.   FData[(FCount-1)][I1].T := F[1].T;
  186.   FData[(FCount-1)][I2].T := F[2].T;
  187.   FData[(FCount-1)][0].M := CurMaterial;
  188.   FData[(FCount-1)][I1].M := CurMaterial;
  189.   FData[(FCount-1)][I2].M := CurMaterial;
  190.   for P := 4 to FVCount do begin
  191.     Inc(FCount);
  192.     if Length(FData) < FCount then SetLength(FData, Length(FData) + ImportCapacityStep);
  193.     FData[(FCount-1)][0].V := F[0].V;
  194.     FData[(FCount-1)][I1].V := F[P-2].V;
  195.     FData[(FCount-1)][I2].V := F[P-1].V;
  196.     FData[(FCount-1)][0].N := F[0].N;
  197.     FData[(FCount-1)][I1].N := F[P-2].N;
  198.     FData[(FCount-1)][I2].N := F[P-1].N;
  199.     FData[(FCount-1)][0].T := F[0].T;
  200.     FData[(FCount-1)][I1].T := F[P-2].T;
  201.     FData[(FCount-1)][I2].T := F[P-1].T;
  202.     FData[(FCount-1)][0].M := CurMaterial;
  203.     FData[(FCount-1)][I1].M := CurMaterial;
  204.     FData[(FCount-1)][I2].M := CurMaterial;
  205.   end;
  206.   SetLength(F, 0);
  207. end;
  208. procedure GetNormal(V1, V2, V3 : word; var N: TVector3s);
  209. begin
  210.   N.X := -((VData[V3].Y - VData[V1].Y)*(VData[V2].Z - VData[V1].Z) - (VData[V3].Z - VData[V1].Z)*(VData[V2].Y - VData[V1].Y));
  211.   N.Y := -((VData[V3].Z - VData[V1].Z)*(VData[V2].X - VData[V1].X) - (VData[V3].X - VData[V1].X)*(VData[V2].Z - VData[V1].Z));
  212.   N.Z := -((VData[V3].X - VData[V1].X)*(VData[V2].Y - VData[V1].Y) - (VData[V3].Y - VData[V1].Y)*(VData[V2].X - VData[V1].X));
  213.   N := NormalizeVector3s(N);
  214. end;
  215. procedure CalcNormals;
  216. var N: TVector3s; i: Integer;
  217. begin
  218.   NCount := VCount;
  219.   SetLength(NData, NCount);
  220.   for i := 0 to NCount-1 do NData[i] := ZeroVector3s;
  221.   for i := 0 to FCount-1 do begin
  222.     GetNormal(FData[i][0].V ,FData[i][1].V, FData[i][2].V, N);
  223.     NData[FData[i][0].V] := AddVector3s(NData[FData[i][0].V], N);
  224.     NData[FData[i][1].V] := AddVector3s(NData[FData[i][1].V], N);
  225.     NData[FData[i][2].V] := AddVector3s(NData[FData[i][2].V], N);
  226.     FData[i][0].N := FData[i][0].V; FData[i][1].N := FData[i][1].V; FData[i][2].N := FData[i][2].V;
  227.   end;
  228.   for i := 0 to NCount-1 do NData[i] := NormalizeVector3s(NData[i]);
  229. end;