问题描述
我正在尝试将我的.obj文件转换为.h头文件,但我收到无法使用'defined(@array)'(也许您应该只忽略define()吗?)"警告,并且没有创建.h文件.
I'm trying to convert my .obj file to a .h header file, but i'm getting "Can't use 'defined(@array)' (Maybe you should just omit the defined()?)" warning and no .h files has created.
我尝试将@center
替换为$center
或省略defined()
,但是它会创建.exe文件!
我在某个地方读到它可能是perl版本的问题,我的版本是5.22,我找不到尝试使用的更高版本.
I've tried replacing @center
to $center
or omintting defined()
but it creates .exe file!
I've read somewhere that it may be a perl version problem, mine is 5.22 and I couldn't find higher versions to try.
更新1:
我已经将"obj2opengl.pl"和"myobject.obj"放在同一文件夹中.并尝试在console(win10)中使用以下代码进行转换:c:\obj2openglfolder>obj2opengl.pl myobject.obj
Update1:
I've put the "obj2opengl.pl " and "myobject.obj" in the same folder. and trying to convert it with this code in console(win10):c:\obj2openglfolder>obj2opengl.pl myobject.obj
Update2:
这是导致问题的line154代码:
Update2:
This is the line154 code that cause the problem:
if(defined(@center)) {
$xcen = $center[0];
$ycen = $center[1];
$zcen = $center[2];
}
Update3:
这是整个代码:
Update3:
this is the whole code:
# -----------------------------------------------------------------
# Main Program
# -----------------------------------------------------------------
handleArguments();
# derive center coords and scale factor if neither provided nor disabled
unless(defined($scalefac) && defined($xcen)) {
calcSizeAndCenter();
}
if($verbose) {
printInputAndOptions();
}
# TODO check integrity: Does every referenced vertex, normal and coord
exist?
loadData();
normalizeNormals();
if($verbose) {
printStatistics();
}
writeOutput();
# -----------------------------------------------------------------
# Sub Routines
# -----------------------------------------------------------------
sub handleArguments() {
my $help = 0;
my $man = 0;
my $noscale = 0;
my $nomove = 0;
$verbose = 1;
$errorInOptions = !GetOptions (
"help" => \$help,
"man" => \$man,
"noScale" => \$noscale,
"scale=f" => \$scalefac,
"noMove" => \$nomove,
"center=f{3}" => \@center,
"outputFilename=s" => \$outFilename,
"nameOfObject=s" => \$object,
"verbose!" => \$verbose,
);
if($noscale) {
$scalefac = 1;
}
if($nomove) {
@center = (0, 0, 0);
}
if(@center) {
$xcen = $center[0];
$ycen = $center[1];
$zcen = $center[2];
}
if($#ARGV == 0) {
my ($file, $dir, $ext) = fileparse($ARGV[0], qr/\.[^.]*/);
$inFilename = $dir . $file . $ext;
} else {
$errorInOptions = true;
}
# (optional) derive output filename from input filename
unless($errorInOptions || defined($outFilename)) {
my ($file, $dir, $ext) = fileparse($inFilename, qr/\.[^.]*/);
$outFilename = $dir . $file . ".h";
}
# (optional) define object name from output filename
unless($errorInOptions || defined($object)) {
my ($file, $dir, $ext) = fileparse($outFilename, qr/\.[^.]*/);
$object = $file;
}
($inFilename ne $outFilename) or
die ("Input filename must not be the same as output filename")
unless($errorInOptions);
if($errorInOptions || $man || $help) {
pod2usage(-verbose => 2) if $man;
pod2usage(-verbose => 1) if $help;
pod2usage();
}
# check wheter file exists
open ( INFILE, "<$inFilename" )
|| die "Can't find file '$inFilename' ...exiting \n";
close(INFILE);
}
# Stores center of object in $xcen, $ycen, $zcen
# and calculates scaling factor $scalefac to limit max
# side of object to 1.0 units
sub calcSizeAndCenter() {
open ( INFILE, "<$inFilename" )
|| die "Can't find file $inFilename...exiting \n";
$numVerts = 0;
my (
$xsum, $ysum, $zsum,
$xmin, $ymin, $zmin,
$xmax, $ymax, $zmax,
);
while ( $line = <INFILE> )
{
chop $line;
if ($line =~ /v\s+.*/)
{
$numVerts++;
@tokens = split(' ', $line);
$xsum += $tokens[1];
$ysum += $tokens[2];
$zsum += $tokens[3];
if ( $numVerts == 1 )
{
$xmin = $tokens[1];
$xmax = $tokens[1];
$ymin = $tokens[2];
$ymax = $tokens[2];
$zmin = $tokens[3];
$zmax = $tokens[3];
}
else
{
if ($tokens[1] < $xmin)
{
$xmin = $tokens[1];
}
elsif ($tokens[1] > $xmax)
{
$xmax = $tokens[1];
}
if ($tokens[2] < $ymin)
{
$ymin = $tokens[2];
}
elsif ($tokens[2] > $ymax)
{
$ymax = $tokens[2];
}
if ($tokens[3] < $zmin)
{
$zmin = $tokens[3];
}
elsif ($tokens[3] > $zmax)
{
$zmax = $tokens[3];
}
}
}
}
close INFILE;
# Calculate the center
unless(defined($xcen)) {
$xcen = $xsum / $numVerts;
$ycen = $ysum / $numVerts;
$zcen = $zsum / $numVerts;
}
# Calculate the scale factor
unless(defined($scalefac)) {
my $xdiff = ($xmax - $xmin);
my $ydiff = ($ymax - $ymin);
my $zdiff = ($zmax - $zmin);
if ( ( $xdiff >= $ydiff ) && ( $xdiff >= $zdiff ) )
{
$scalefac = $xdiff;
}
elsif ( ( $ydiff >= $xdiff ) && ( $ydiff >= $zdiff ) )
{
$scalefac = $ydiff;
}
else
{
$scalefac = $zdiff;
}
$scalefac = 1.0 / $scalefac;
}
}
sub printInputAndOptions() {
print "Input file : $inFilename\n";
print "Output file : $outFilename\n";
print "Object name : $object\n";
print "Center : <$xcen, $ycen, $zcen>\n";
print "Scale by : $scalefac\n";
}
sub printStatistics() {
print "----------------\n";
print "Vertices : $numVerts\n";
print "Faces : $numFaces\n";
print "Texture Coords : $numTexture\n";
print "Normals : $numNormals\n";
}
# reads vertices into $xcoords[], $ycoords[], $zcoords[]
# where coordinates are moved and scaled according to
# $xcen, $ycen, $zcen and $scalefac
# reads texture coords into $tx[], $ty[]
# where y coordinate is mirrowed
# reads normals into $nx[], $ny[], $nz[]
# but does not normalize, see normalizeNormals()
# reads faces and establishes lookup data where
# va_idx[], vb_idx[], vc_idx[] for vertices
# ta_idx[], tb_idx[], tc_idx[] for texture coords
# na_idx[], nb_idx[], nc_idx[] for normals
# store indizes for the former arrays respectively
# also, $face_line[] store actual face string
sub loadData {
$numVerts = 0;
$numFaces = 0;
$numTexture = 0;
$numNormals = 0;
open ( INFILE, "<$inFilename" )
|| die "Can't find file $inFilename...exiting \n";
while ($line = <INFILE>)
{
chop $line;
# vertices
if ($line =~ /v\s+.*/)
{
@tokens= split(' ', $line);
$x = ( $tokens[1] - $xcen ) * $scalefac;
$y = ( $tokens[2] - $ycen ) * $scalefac;
$z = ( $tokens[3] - $zcen ) * $scalefac;
$xcoords[$numVerts] = $x;
$ycoords[$numVerts] = $y;
$zcoords[$numVerts] = $z;
$numVerts++;
}
# texture coords
if ($line =~ /vt\s+.*/)
{
@tokens= split(' ', $line);
$x = $tokens[1];
$y = 1 - $tokens[2];
$tx[$numTexture] = $x;
$ty[$numTexture] = $y;
$numTexture++;
}
#normals
if ($line =~ /vn\s+.*/)
{
@tokens= split(' ', $line);
$x = $tokens[1];
$y = $tokens[2];
$z = $tokens[3];
$nx[$numNormals] = $x;
$ny[$numNormals] = $y;
$nz[$numNormals] = $z;
$numNormals++;
}
# faces
if ($line =~ /f\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)(\s+([^ ]+))?/)
{
@a = split('/', $1);
@b = split('/', $2);
@c = split('/', $3);
$va_idx[$numFaces] = $a[0]-1;
$ta_idx[$numFaces] = $a[1]-1;
$na_idx[$numFaces] = $a[2]-1;
$vb_idx[$numFaces] = $b[0]-1;
$tb_idx[$numFaces] = $b[1]-1;
$nb_idx[$numFaces] = $b[2]-1;
$vc_idx[$numFaces] = $c[0]-1;
$tc_idx[$numFaces] = $c[1]-1;
$nc_idx[$numFaces] = $c[2]-1;
$face_line[$numFaces] = $line;
$numFaces++;
# ractangle => second triangle
if($5 != "")
{
@d = split('/', $5);
$va_idx[$numFaces] = $a[0]-1;
$ta_idx[$numFaces] = $a[1]-1;
$na_idx[$numFaces] = $a[2]-1;
$vb_idx[$numFaces] = $d[0]-1;
$tb_idx[$numFaces] = $d[1]-1;
$nb_idx[$numFaces] = $d[2]-1;
$vc_idx[$numFaces] = $c[0]-1;
$tc_idx[$numFaces] = $c[1]-1;
$nc_idx[$numFaces] = $c[2]-1;
$face_line[$numFaces] = $line;
$numFaces++;
}
}
}
close INFILE;
}
sub normalizeNormals {
for ( $j = 0; $j < $numNormals; ++$j)
{
$d = sqrt ( $nx[$j]*$nx[$j] + $ny[$j]*$ny[$j] + $nz[$j]*$nz[$j] );
if ( $d == 0 )
{
$nx[$j] = 1;
$ny[$j] = 0;
$nz[$j] = 0;
}
else
{
$nx[$j] = $nx[$j] / $d;
$ny[$j] = $ny[$j] / $d;
$nz[$j] = $nz[$j] / $d;
}
}
}
sub fixedIndex {
local $idx = $_[0];
local $num = $_[1];
if($idx >= 0)
{
$idx;
} else {
$num + $idx + 1;
}
}
sub writeOutput {
open ( OUTFILE, ">$outFilename" )
|| die "Can't create file $outFilename ... exiting\n";
print OUTFILE "/*\n";
print OUTFILE "created with obj2opengl.pl\n\n";
# some statistics
print OUTFILE "source file : $inFilename\n";
print OUTFILE "vertices : $numVerts\n";
print OUTFILE "faces : $numFaces\n";
print OUTFILE "normals : $numNormals\n";
print OUTFILE "texture coords : $numTexture\n";
print OUTFILE "\n\n";
# example usage
print OUTFILE "// include generated arrays\n";
print OUTFILE "#import \"".$outFilename."\"\n";
print OUTFILE "\n";
print OUTFILE "// set input data to arrays\n";
print OUTFILE "glVertexPointer(3, GL_FLOAT, 0, ".$object."Verts);\n";
print OUTFILE "glNormalPointer(GL_FLOAT, 0, ".$object."Normals);\n"
if $numNormals > 0;
print OUTFILE "glTexCoordPointer(2, GL_FLOAT, 0, ".$object."TexCoords);\n"
if $numTexture > 0;
print OUTFILE "\n";
print OUTFILE "// draw data\n";
print OUTFILE "glDrawArrays(GL_TRIANGLES, 0, ".$object."NumVerts);\n";
print OUTFILE "*/\n\n";
# needed constant for glDrawArrays
print OUTFILE "unsigned int ".$object."NumVerts = ".($numFaces * 3).";\n\n";
# write verts
print OUTFILE "float ".$object."Verts \[\] = {\n";
for( $j = 0; $j < $numFaces; $j++)
{
$ia = fixedIndex($va_idx[$j], $numVerts);
$ib = fixedIndex($vb_idx[$j], $numVerts);
$ic = fixedIndex($vc_idx[$j], $numVerts);
print OUTFILE " // $face_line[$j]\n";
print OUTFILE " $xcoords[$ia], $ycoords[$ia], $zcoords[$ia],\n";
print OUTFILE " $xcoords[$ib], $ycoords[$ib], $zcoords[$ib],\n";
print OUTFILE " $xcoords[$ic], $ycoords[$ic], $zcoords[$ic],\n";
}
print OUTFILE "};\n\n";
# write normals
if($numNormals > 0) {
print OUTFILE "float ".$object."Normals \[\] = {\n";
for( $j = 0; $j < $numFaces; $j++) {
$ia = fixedIndex($na_idx[$j], $numNormals);
$ib = fixedIndex($nb_idx[$j], $numNormals);
$ic = fixedIndex($nc_idx[$j], $numNormals);
print OUTFILE " // $face_line[$j]\n";
print OUTFILE " $nx[$ia], $ny[$ia], $nz[$ia],\n";
print OUTFILE " $nx[$ib], $ny[$ib], $nz[$ib],\n";
print OUTFILE " $nx[$ic], $ny[$ic], $nz[$ic],\n";
}
print OUTFILE "};\n\n";
}
# write texture coords
if($numTexture) {
print OUTFILE "float ".$object."TexCoords \[\] = {\n";
for( $j = 0; $j < $numFaces; $j++) {
$ia = fixedIndex($ta_idx[$j], $numTexture);
$ib = fixedIndex($tb_idx[$j], $numTexture);
$ic = fixedIndex($tc_idx[$j], $numTexture);
print OUTFILE " // $face_line[$j]\n";
print OUTFILE " $tx[$ia], $ty[$ia],\n";
print OUTFILE " $tx[$ib], $ty[$ib],\n";
print OUTFILE " $tx[$ic], $ty[$ic],\n";
}
print OUTFILE "};\n\n";
}
close OUTFILE;
}
推荐答案
defined(@array)
用于返回数组是否为空.这是一个错误.
defined(@array)
used to return whether the array was empty or not. This was a bug.
defined(@array)
应该始终返回true(因为始终定义数组中的元素数).
defined(@array)
should always return true (since the number of element in an array is always defined).
defined
的特殊用法(而不是无用的)可以让用户知道他们在做错了什么以及如何解决它,而不是修复bug(导致代码无声地出现故障).
Rather than fixing the bug (causing code to silently malfunction), that particular (and useless) use of defined
now lets the user know they are doing something wrong and how to fix it.
如错误消息所提示,只需使用if (@array)
来检查数组是否为空.
As the error message suggests, simply use if (@array)
to check if the array is empty.
这篇关于将.obj转换为.h时不能使用'defined(@array)'警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!