📄 dgtoolssave3ds.pas
字号:
// 3D Studio max exporter by Dave Gravel.
// This is a personal code not public....
// 2007
unit dgToolsSave3DS;
interface
uses Windows, Classes, SysUtils, Math, GLVectorFileObjects, Opengl1x,
VectorLists, Dialogs, VectorTypes, VectorGeometry, PersistentClasses, MeshUtils,
GLCrossPlatform, GLMisc, GLFileOBJ, GLTexture, GLMeshOptimizer, GLFile3DS, GLFileSMD,
JPEG;
const
M3DMAGIC = ( $4D4D );
M3D_VERSION = ( $0002 );
MDATA = ( $3D3D );
MESH_VERSION = ( $3D3E );
MAT_ENTRY = ( $AFFF );
MASTER_SCALE = ( $0100 );
NAMED_OBJECT = ( $4000 );
N_TRI_OBJECT = ( $4100 );
POINT_ARRAY = ( $4110 );
TEX_VERTS = ( $4140 );
MESH_MATRIX = ( $4160 );
FACE_ARRAY = ( $4120 );
MSH_MAT_GROUP = ( $4130 );
SMOOTH_GROUP = ( $4150 );
MESH_COLOR = ( $4165 );
MAT_NAME = ( $A000 );
MAT_AMBIENT = ( $A010 );
MAT_DIFFUSE = ( $A020 );
MAT_SPECULAR = ( $A030 );
COLOR_24 = ( $0011 );
MAT_TEXMAP = ( $A200 );
MAT_MAPNAME = ( $A300 );
MAT_MAP_UOFFSET = ( $A358 );
MAT_MAP_VOFFSET = ( $A35A );
MAT_MAP_USCALE = ( $A354 );
MAT_MAP_VSCALE = ( $A356 );
A_S = ( 6 + 4 );
A_BS = ( 6 + 2 + 8 );
A_BG = ( 6 + 2 + 12 );
D_0 = ( 0 );
D_A = ( 1 );
D_B = ( 2 );
D_C = ( 3 );
D_D = ( 4 );
D_E = ( 6 );
D_I = ( 8 );
D_F = ( 12 );
D_J = ( 16 );
D_G = ( 24 );
D_H = ( 48 );
type
vec3f = array[D_0..D_B] of single;
vec2f = array[D_0..D_A] of single;
vec3l = array[D_0..D_B] of LongWord;
T3DSMeshObject = class;
T3DSMeshMaterial = class
private
mMesh: T3DSMeshObject;
mName: String;
mMaterialMapName: String;
mFaces: TFaceGroup;
mUScale: single;
mVScale: single;
mUOffset: single;
mVOffset: single;
public
function NameLength: Cardinal;
function Color24Length: Cardinal;
function AmbientLength: Cardinal;
function DiffuseLength: Cardinal;
function SpecularLength: Cardinal;
function MaterialMapLength: Cardinal;
function MaterialMapNameLength: Cardinal;
function MaterialFaceLength: Cardinal;
function MapUScaleLength: Cardinal;
function MapVScaleLength: Cardinal;
function MapUOffsetLength: Cardinal;
function MapVOffsetLength: Cardinal;
constructor Create( ID: integer; Mesh: T3DSMeshObject; cMesh: TGLBaseMesh; cFaces: TFaceGroup );
destructor Destroy; override;
end;
T3DSMeshObject = class
private
mFObjList: TList;
mMaterial: array of T3DSMeshMaterial;
mObject: TMeshObject;
mName: string;
mFaceGroups: TFaceGroups;
mTexList: TAffineVectorList;
mVerList: TAffineVectorList;
mFacList: TIntegerList;
mNorList: TAffineVectorList;
procedure CollectData;
procedure ClearData;
procedure WriteVertices;
procedure FaceDataMesh;
procedure TexDataCoords;
public
constructor Create( mObj: TMeshObject );
destructor Destroy; override;
//
function VCount: Cardinal;
function TCount: Cardinal;
function FCount: Cardinal;
function TriMeshLength: Cardinal;
function SmoothLength: Cardinal;
function NameLength: Cardinal;
function TexLength: Cardinal;
function VerLength: Cardinal;
function FacLength: Cardinal;
function MatrixLength: Cardinal;
end;
TMappingMode = (mmSpherical,mmPlanar,mmCylindric);
type
TOXToolSave3DS = class( TObject )
private
FMeshObject3DS: array of T3DSMeshObject;
FMappingMode: TMappingMode;
//
FMesh: TGLBaseMesh;
function GetByte( Value: TColor; Shift: byte ): byte;
public
Constructor Create( cMesh: TGLBaseMesh );
Destructor Destroy; override;
procedure SaveTo3DS( const FileName: string );
property MappingMode: TMappingMode read FMappingMode write FMappingMode;
end;
var
LastChunk: string = '';
implementation
uses ApplicationFileIO, XOpenGL, GLUtils;
function T3DSMeshMaterial.NameLength: Cardinal;
begin
result:= ( Length( mName ) + D_A );
end;
function T3DSMeshMaterial.MapUScaleLength: Cardinal;
begin
result:= ( D_E + D_D );
end;
function T3DSMeshMaterial.MapVScaleLength: Cardinal;
begin
result:= ( D_E + D_D );
end;
function T3DSMeshMaterial.MapUOffsetLength: Cardinal;
begin
result:= ( D_E + D_D );
end;
function T3DSMeshMaterial.MapVOffsetLength: Cardinal;
begin
result:= ( D_E + D_D );
end;
function T3DSMeshMaterial.Color24Length: Cardinal;
begin
result:= ( D_E + D_C );
end;
function T3DSMeshMaterial.MaterialFaceLength: Cardinal;
begin
result:= ( D_E + Length( mName ) + D_A + D_B + D_B * INTEGER( mMesh.FCount ) );
end;
function T3DSMeshMaterial.MaterialMapNameLength: Cardinal;
begin
result:= ( Length( mMaterialMapName ) + D_A );
end;
function T3DSMeshMaterial.MaterialMapLength: Cardinal;
begin
if ( mMaterialMapName <> '' ) then
result:= ( D_E + MaterialMapNameLength + MapUScaleLength + MapVScaleLength + MapUOffsetLength + MapVOffsetLength )
else
result:= ( D_E );
end;
function T3DSMeshMaterial.AmbientLength: Cardinal;
begin
result:= ( D_E + Color24Length );
end;
function T3DSMeshMaterial.DiffuseLength: Cardinal;
begin
result:= ( D_E + Color24Length );
end;
function T3DSMeshMaterial.SpecularLength: Cardinal;
begin
result:= ( D_E + Color24Length );
end;
constructor T3DSMeshMaterial.Create( ID: integer; Mesh: T3DSMeshObject; cMesh: TGLBaseMesh; cFaces: TFaceGroup );
begin
mUScale:= 0.0;
mVScale:= 0.0;
mUOffset:= 0.0;
mVOffset:= 0.0;
mFaces:= cFaces;
mMaterialMapName:= '';
mMesh:= Mesh;
if assigned( cMesh.MaterialLibrary ) then begin
if assigned( cMesh.MaterialLibrary.LibMaterialByName( mFaces.MaterialName ) ) then begin
mMaterialMapName:= cMesh.MaterialLibrary.LibMaterialByName( mFaces.MaterialName ).
Material.Texture.Image.TextureFileName;
mUScale:= cMesh.MaterialLibrary.LibMaterialByName( mFaces.MaterialName ).TextureScale.X;
mVScale:= cMesh.MaterialLibrary.LibMaterialByName( mFaces.MaterialName ).TextureScale.Y;
mUOffset:= cMesh.MaterialLibrary.LibMaterialByName( mFaces.MaterialName ).TextureOffset.X;
mVOffset:= cMesh.MaterialLibrary.LibMaterialByName( mFaces.MaterialName ).TextureOffset.Y;
end;
end;
mName:= cFaces.MaterialName;
if mName = '' then mName:= 'oxMat' + IntToStr( ID );
end;
destructor T3DSMeshMaterial.Destroy;
begin
mFaces:= nil;
inherited Destroy;
end;
constructor T3DSMeshObject.Create( mObj: TMeshObject );
begin
mObject:= mObj;
mName:= mObject.Name;
mFaceGroups:= nil;
mFaceGroups:= TFaceGroups.Create;
mFaceGroups.Assign( mObject.FaceGroups );
mTexList:= TAffineVectorList.Create;
mVerList:= TAffineVectorList.Create;
mFacList:= TIntegerList.Create;
mNorList:= TAffineVectorList.Create;
CollectData;
end;
procedure T3DSMeshObject.WriteVertices;
var
i: integer;
begin
with mObject.Vertices do begin
for i:= D_0 to Count -D_A do begin
mVerList.Add( List^[i][D_0], List^[i][D_A], List^[i][D_B] );
mNorList.Add( mObject.Normals.List^[i][D_0],
mObject.Normals.List^[i][D_A],
mObject.Normals.List^[i][D_B] );
end;
end;
end;
procedure T3DSMeshObject.FaceDataMesh;
var
i, j: integer;
FaceGroup: TFaceGroup;
TmpIntegerList: TIntegerList;
begin
for i:= D_0 to mFaceGroups.Count -D_A do begin
FaceGroup:= mFaceGroups[i];
TmpIntegerList:= TFGVertexIndexList( FaceGroup ).VertexIndices;
for j:= D_0 to ( TmpIntegerList.Count div D_C ) -D_A do begin
mFacList.Add( TmpIntegerList.List^[j * D_C + D_0] );
mFacList.Add( TmpIntegerList.List^[j * D_C + D_A] );
mFacList.Add( TmpIntegerList.List^[j * D_C + D_B] );
end;
end;
end;
procedure T3DSMeshObject.TexDataCoords;
var i: integer;
la: single;
lu: single;
begin
with mObject do begin
if ( TexCoords.Count > 0 ) and (TexCoords.Count = Vertices.Count) then begin
for i:= D_0 to TexCoords.Count -D_A do begin
mTexList.Add( TexCoords.List^[i][D_0], TexCoords.List^[i][D_A] );
end;
end else begin
// mmCylindric;//mmSpherical;//mmPlanar; to add later!!!
for i:= D_0 to mVerList.Count -D_A do begin
la:= ArcSin( mNorList.List^[i][0] ) / cPI + 0.5;
lu:= ArcSin( mNorList.List^[i][1] ) / cPI + 0.5;
mTexList.Add( la, lu );
end;
end;
end;
end;
procedure T3DSMeshObject.CollectData;
begin
WriteVertices;
FaceDataMesh;
TexDataCoords;
end;
procedure T3DSMeshObject.ClearData;
begin
mName:= '';
mFaceGroups.Clear;
mTexList.Clear;
mVerList.Clear;
mFacList.Clear;
mNorList.Clear;
end;
function T3DSMeshObject.NameLength: Cardinal;
begin
result:= ( Length( mName ) + D_A );
end;
function T3DSMeshObject.TexLength: Cardinal;
begin
result:= ( D_E + D_B + D_I * TCount );
end;
function T3DSMeshObject.VerLength: Cardinal;
begin
result:= ( D_E + D_B + D_F * VCount );
end;
function T3DSMeshObject.FacLength: Cardinal;
var i: integer;
begin
result:= 0;
for i:= 0 to mFObjList.Count -1 do begin
result:= ( result + D_E + D_B + D_I * FCount + SmoothLength + mMaterial[i].MaterialFaceLength );
end;
end;
function T3DSMeshObject.SmoothLength: Cardinal;
begin
result:= ( D_E + FCount * D_D );
end;
function T3DSMeshObject.MatrixLength: Cardinal;
begin
result:= ( D_E + D_H );
end;
function T3DSMeshObject.TriMeshLength: Cardinal;
begin
result:= ( D_E + VerLength + TexLength + FacLength {+ MatrixLength} );
end;
function T3DSMeshObject.VCount: Cardinal;
begin
result:= mVerList.Count;
end;
function T3DSMeshObject.TCount: Cardinal;
begin
result:= mTexList.Count;
end;
function T3DSMeshObject.FCount: Cardinal;
begin
result:= ( mFacList.Count Div D_C );
end;
destructor T3DSMeshObject.Destroy;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -