⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glfile3ds.pas

📁 这是三D开发的一些源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//
// This unit is part of the GLScene Project, http://glscene.org
//
{: GLFile3DS<p>

	3DStudio 3DS vector file format implementation.<p>

	<b>History :</b><font size=-1><ul>
      <li>31/03/07 - DaStr - Added $I GLScene.inc
      <li>24/03/07 - DaStr - Added explicit pointer dereferencing
                             (thanks Burkhard Carstens) (Bugtracker ID = 1678644)
      <li>28/01/07 - DaStr - Added transparency and opacity texture support (thanks DIVON)
      <li>09/12/04 - LR - Add Integer cast line 94 for Linux
      <li>25/10/04 - SG - Added lightmap (3DS IllumMap) support
      <li>05/06/03 - SG - Separated from GLVectorFileObjects.pas
	</ul></font>
}
unit GLFile3DS;

interface

{$I GLScene.inc}

uses
  Classes, SysUtils, GLVectorFileObjects, GLTexture, ApplicationFileIO,
  VectorGeometry, File3DS, Types3DS;

type
   // TGL3DSVectorFile
   //
   {: The 3DStudio vector file.<p>
      Uses 3DS import library by Mike Lischke (http://www.lishcke-online.de).<p>
      A 3DS file may contain material information and require textures when
      loading. Only the primary and opacity texture maps are used by GLScene,
      bump mapping, etc. are ignored as of now. }
   TGL3DSVectorFile = class (TVectorFile)
      public
         { Public Declarations }
         class function Capabilities : TDataFileCapabilities; override;
         procedure LoadFromStream(aStream : TStream); override;
   end;

// ------------------------------------------------------------------
// ------------------------------------------------------------------
// ------------------------------------------------------------------
implementation
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// ------------------------------------------------------------------

// ------------------
// ------------------ TGL3DSVectorFile ------------------
// ------------------

// Capabilities
//
class function TGL3DSVectorFile.Capabilities : TDataFileCapabilities;
begin
   Result:=[dfcRead,dfcWrite];
end;

// LoadFromStream
//
procedure TGL3DSVectorFile.LoadFromStream(aStream: TStream);
type
   TSmoothIndexEntry = array[0..31] of Cardinal;
   PSmoothIndexArray = ^TSmoothIndexArray;
   TSmoothIndexArray = array[0..MaxInt shr 8] of TSmoothIndexEntry;
var
   Marker: PByteArray;
   CurrentVertexCount: Integer;
   SmoothIndices: PSmoothIndexArray;
   mesh : TMeshObject;
   hasLightmap : Boolean;

   //--------------- local functions -------------------------------------------

   function GetOrAllocateMaterial(materials : TMaterialList; const name : String) : String;
   var
      material : PMaterial3DS;
      specColor : TVector;
      matLib : TGLMaterialLibrary;
      libMat : TGLLibMaterial;
      opacMat: TGLLibMaterial;
   begin
      material:=Materials.MaterialByName[Name];
      Assert(Assigned(material));
      if GetOwner is TGLBaseMesh then begin
         matLib:=TGLBaseMesh(GetOwner).MaterialLibrary;
         if Assigned(matLib) then begin
            Result:=name;
            libMat:=matLib.Materials.GetLibMaterialByName(name);
            if not Assigned(libMat) then begin
               libMat:=matLib.Materials.Add;
               libMat.Name:=name;
               with libMat.Material.FrontProperties do begin
                  Ambient.Color:=VectorMake(material.Ambient.R, material.Ambient.G, material.Ambient.B, 1);
                  //Yep, material transparency is stored as a negative value :P
                  Diffuse.Color:=VectorMake(material.Diffuse.R, material.Diffuse.G, material.Diffuse.B,1 - material.Transparency);
                  specColor:=VectorMake(material.Specular.R, material.Specular.G, material.Specular.B, 1);
                  ScaleVector(specColor, 1 - material.Shininess);
                  Specular.Color:=specColor;
                  Shininess:=MaxInteger(0, Integer(Round((1 - material.ShinStrength) * 128)));
                  if material.Transparency <> 0 then
                    libMat.Material.BlendingMode:=bmTransparency;
               end;

               if Trim(material.Texture.Map.NameStr)<>'' then
                  try
                     with libMat.Material.Texture do begin
                        Image.LoadFromFile(material.Texture.Map.NameStr);
                        Disabled:=False;
                        TextureMode:=tmModulate;
                     end;
                  except
                     on E: ETexture do begin
                        if not Owner.IgnoreMissingTextures then
                           raise;
                     end;
                  end;

               if Trim(material.Opacity.Map.NameStr) <> '' then
                 try
                 OpacMat:=matLib.Materials.Add;
                 OpacMat.Material.Texture.Image.LoadFromFile(material.Opacity.Map.NameStr);
                 OpacMat.Material.Texture.Disabled:=false;
                 OpacMat.Material.Texture.ImageAlpha:=tiaAlphaFromIntensity;
                 OpacMat.Material.Texture.TextureMode:=tmModulate;
                 OpacMat.Name:=material.Opacity.Map.NameStr;
                 LibMat.Texture2Name:=OpacMat.Name;
                 LibMat.Material.BlendingMode:=bmTransparency;
                  except
                     on E: ETexture do begin
                        if not Owner.IgnoreMissingTextures then
                           raise;
                     end;
                  end;
            end;
         end else Result:='';
      end else Result:='';
   end;

   function GetOrAllocateLightMap(materials : TMaterialList; const name : String) : Integer;
   var
      material : PMaterial3DS;
      matLib : TGLMaterialLibrary;
      libMat : TGLLibMaterial;
   begin
      Result:=-1;
      material:=Materials.MaterialByName[Name];
      Assert(Assigned(material));
      if GetOwner is TGLBaseMesh then begin
         matLib:=TGLBaseMesh(GetOwner).LightmapLibrary;
         if Assigned(matLib) then begin
            if Trim(material.IllumMap.Map.NameStr)<>'' then begin
               libMat:=matLib.Materials.GetLibMaterialByName(material.IllumMap.Map.NameStr);
               if not Assigned(libMat) then begin
                  libMat:=matLib.Materials.Add;
                  libMat.Name:=material.IllumMap.Map.NameStr;
                  try
                     with libMat.Material.Texture do begin
                        Image.LoadFromFile(material.IllumMap.Map.NameStr);
                        Disabled:=False;
                        TextureMode:=tmModulate;
                     end;
                  except
                     on E: ETexture do begin
                        if not Owner.IgnoreMissingTextures then
                           raise;
                     end;
                  end;
               end;
               Result:=libmat.Index;
               hasLightMap:=True;
            end;
         end;
      end;
   end;

   //----------------------------------------------------------------------

   function IsVertexMarked(P: Pointer; Index: Integer): Boolean; assembler;
      // tests the Index-th bit, returns True if set else False
   asm
                     BT [EAX], EDX
                     SETC AL
   end;

   //---------------------------------------------------------------------------

   function MarkVertex(P: Pointer; Index: Integer): Boolean; assembler;
      // sets the Index-th bit and return True if it was already set else False
   asm
                     BTS [EAX], EDX
                     SETC AL
   end;

   //---------------------------------------------------------------------------

   procedure StoreSmoothIndex(ThisIndex, SmoothingGroup, NewIndex: Cardinal; P: Pointer);
      // Stores new vertex index (NewIndex) into the smooth index array of vertex ThisIndex
      // using field SmoothingGroup, which must not be 0.
      // For each vertex in the vertex array (also for duplicated vertices) an array of 32 cardinals
      // is maintained (each for one possible smoothing group. If a vertex must be duplicated because
      // it has no smoothing group or a different one then the index of the newly created vertex is
      // stored in the SmoothIndices to avoid loosing the conjunction between not yet processed vertices
      // and duplicated vertices.
      // Note: Only one smoothing must be assigned per vertex. Some available models break this rule and
      //       have more than one group assigned to a face. To make the code fail safe the group ID
      //       is scanned for the lowest bit set.
   asm
                   PUSH EBX
                   BSF EBX, EDX                  // determine smoothing group index (convert flag into an index)
                   MOV EDX, [P]                  // get address of index array
                   SHL EAX, 7                    // ThisIndex * SizeOf(TSmoothIndexEntry)
                   ADD EAX, EDX
                   LEA EDX, [4 * EBX + EAX]      // Address of array + vertex index + smoothing group index
                   MOV [EDX], ECX
                   POP EBX
   end;

   //---------------------------------------------------------------------------

   function GetSmoothIndex(ThisIndex, SmoothingGroup: Cardinal; P: Pointer): Integer;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -