/usr/src/castle-game-engine-6.4/x3d/x3dloadinternalutils.pas is in castle-game-engine-src 6.4+dfsg1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | {
Copyright 2003-2017 Michalis Kamburelis.
This file is part of "Castle Game Engine".
"Castle Game Engine" is free software; see the file COPYING.txt,
included in this distribution, for details about the copyright.
"Castle Game Engine" is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
}
{ Utilities for converting other 3D model formats into VRML/X3D. }
unit X3DLoadInternalUtils;
{$I castleconf.inc}
interface
uses CastleVectors, X3DNodes;
const
NiceCreaseAngle = DefaultVRML1CreaseAngle;
function ToX3DName(const S: string): string;
{ Calculate best possible ambientIntensity. This is a float that tries to
satisfy the equation AmbientColor = AmbientIntensity * DiffuseColor.
Suitable for VRML 2.0/X3D Material.ambientIntensity (as there's no
Material.ambientColor in VRML 2.0/X3D). }
function AmbientIntensity(const AmbientColor, DiffuseColor: TVector3): Single; overload;
function AmbientIntensity(const AmbientColor, DiffuseColor: TVector4): Single; overload;
{ Search harder for file named Base inside directory of BaseUrl.
BaseUrl must be an absolute URL, we will extract path from it.
Returns URL relative to BaseUrl.
Automatically uses FixRelativeUrl on Base, fixing backslashes to slashes,
so assuming that this is an old 3D format and backslash should be interpreted
as directory separator (like on Windows).
We prefer to return just Base, if it exists, or when no alternative exists.
When Base doesn't exist but some likely alternative exists (e.g. with
different case), we return it. }
function SearchTextureFile(const BaseUrl: string; Base: string): string;
{ Convert backslashes to slashes. Use for formats where this interpretation
of backslash (instead of %-encoding actual backslash, see
https://sourceforge.net/p/castle-engine/tickets/21/ ) seems more common. }
function FixRelativeUrl(const URL: string): string;
implementation
uses SysUtils, Math, URIParser,
CastleStringUtils, CastleFindFiles, CastleLog, CastleURIUtils;
function ToX3DName(const s: string): string;
const
{ We could use here TX3DLexer.VRMLNameChars that contains
*all* allowed characters in X3D name.
But, for readability, better to avoid even more weird characters,
and limit ourselves to the below character set. }
AllowedNameChars = ['a'..'z','A'..'Z','0'..'9'];
NonAllowedNameChars = AllChars - AllowedNameChars;
begin
result := SReplaceChars(S, NonAllowedNameChars, '_');
end;
function AmbientIntensity(const AmbientColor, DiffuseColor: TVector3): Single;
begin
Result := 0;
if not IsZero(DiffuseColor[0]) then
Result := Result + (AmbientColor[0] / DiffuseColor[0]);
if not IsZero(DiffuseColor[1]) then
Result := Result + (AmbientColor[1] / DiffuseColor[1]);
if not IsZero(DiffuseColor[2]) then
Result := Result + (AmbientColor[2] / DiffuseColor[2]);
Result := Result / 3;
end;
function AmbientIntensity(const AmbientColor, DiffuseColor: TVector4): Single;
begin
Result := AmbientIntensity(
AmbientColor.XYZ,
DiffuseColor.XYZ);
end;
function SearchTextureFile(const BaseUrl: string; Base: string): string;
var
SomePathDelim: Integer;
BaseShort, Path: string;
begin
Path := ExtractURIPath(BaseUrl);
Base := FixRelativeUrl(Base);
try
if SearchFileHard(Path, Base, Result) then
Exit;
{ According to https://sourceforge.net/tracker/index.php?func=detail&aid=3305661&group_id=200653&atid=974391
some archives expect search within textures/ subdirectory.
Example on http://www.gfx-3d-model.com/2008/06/house-07/#more-445
for Wavefront OBJ. }
if SearchFileHard(Path + 'textures/', Base, Result) then
begin
Result := 'textures/' + Result;
Exit;
end;
if SearchFileHard(Path + 'Textures/', Base, Result) then
begin
Result := 'Textures/' + Result;
Exit;
end;
{ Some invalid models place full (absolute) path inside texture filename.
Try to handle it, by stripping path part (from any OS), and trying
to match new name. }
SomePathDelim := BackCharsPos(['/', '\'], Base);
if SomePathDelim <> 0 then
begin
BaseShort := SEnding(Base, SomePathDelim + 1);
if SearchFileHard(Path, BaseShort, Result) then
Exit;
if SearchFileHard(Path + 'textures/', BaseShort, Result) then
begin
Result := 'textures/' + Result;
Exit;
end;
if SearchFileHard(Path + 'Textures/', BaseShort, Result) then
begin
Result := 'Textures/' + Result;
Exit;
end;
end;
finally
if Result <> Base then
{ Texture file found, but not under original name }
WritelnWarning('Texture', Format('Exact texture URL "%s" not found, using instead "%s"',
[Base, Result]));
end;
{ default result if nowhere found }
Result := Base;
end;
function FixRelativeUrl(const URL: string): string;
begin
Result := SReplaceChars(URL, '\', '/');
end;
end.
|