如何在函数中返回结果对象?

时间:2014-11-28 16:25:56

标签: javascript 3d three.js

美好的一天,所有! :)

在过去的一个月里,我一直致力于一次性在1个函数中返回2个或更多THREE.js材料的函数。我遇到了一个小问题。出于某种原因,我无法使用此函数返回MeshBasicMaterial对象以及MeshLambertMaterial数据对象。我知道我的代码是正确的,因为我已经超过40次查找错误。

这里是整个代码:

/**
* A function for converting hex <-> dec w/o loss of precision.
*
* The problem is that parseInt("0x12345...") isn't precise enough to convert
* 64-bit integers correctly.
*
* Internally, this uses arrays to encode decimal digits starting with the least
* significant:
* 8 = [8]
* 16 = [6, 1]
* 1024 = [4, 2, 0, 1]
*/

// Adds two arrays for the given base (10 or 16), returning the result.
// This turns out to be the only "primitive" operation we need.

function add(x, y, base)
{

    var z = [];

    var n = Math.max(x.length, y.length);

    var carry = 0;

    var i = 0;

    while (i < n || carry)
    {

        var xi = i < x.length ? x[i] : 0;
        var yi = i < y.length ? y[i] : 0;
        var zi = carry + xi + yi;

        z.push(zi % base);
        carry = Math.floor(zi / base);
        i++;

    }

    return z;

}

// Returns a*x, where x is an array of decimal digits and a is an ordinary
// JavaScript number. base is the number base of the array x.
function multiplyByNumber(num, x, base)
{

    if (num < 0) return null;
    if (num == 0) return [];

    var result = [];
    var power = x;

    while (true)
    {

        if (num & 1)
        {

            result = add(result, power, base);

        }

        num = num >> 1;

        if (num === 0) break;

        power = add(power, power, base);

    }

    return result;

}

function parseToDigitsArray(str, base)
{

    var digits = str.split('');

    var ary = [];

    for (var i = digits.length - 1; i >= 0; i--)
    {

        var n = parseInt(digits[i], base);
        if (isNaN(n)) return null;
        ary.push(n);

    }

    return ary;

}

function convertBase(str, fromBase, toBase)
{

    var digits = parseToDigitsArray(str, fromBase);
    if (digits === null) return null;

    var outArray = [];
    var power = [1];

        for (var i = 0; i < digits.length; i++)
        {

            // invariant: at this point, fromBase^i = power
            if (digits[i])
            {

                outArray = add(outArray, multiplyByNumber(digits[i], power, toBase), toBase);

            }

            power = multiplyByNumber(fromBase, power, toBase);

        }

    var out = '';

        for (var i = outArray.length - 1; i >= 0; i--)
        {

            out += outArray[i].toString(toBase);

        }

    return out;

}

function decToHex(decStr) {
  var hex = convertBase(decStr, 10, 16);
  return hex ? '0x' + hex : null;
}

function hexToDec(hexStr) {
  if (hexStr.substring(0, 2) === '0x') hexStr = hexStr.substring(2);
  hexStr = hexStr.toLowerCase();
  return convertBase(hexStr, 16, 10);
}

function instr(str, val)
{

    if(typeof(str) === 'string')
    {

        str = str.toString(str);
        val = val.toString(val);

        in_str = str.indexOf(val);

        return in_str;

    }

    else

    {

        api_messagebox('Please use a string!');

    }

    return false;

}

function Get_RGBA(hexVal, getwhich)
{

    hexVal = hexVal || '';
    getwhich = getwhich || 0;

    var commaSeperated = 0;

    //if(typeof(hexVal) === 'string')
    //{

        // Removes the first character from the input string
        if(hexVal.length === 8) { hexVal = hexVal.substring(1, hexVal.length); }
        if(hexVal.length === 10) { hexVal = hexVal.substring(0, hexVal.length); }

        // Now let's separate the pairs by a comma
        for (var i = 0; i <= hexVal.length; i++)
        {

            // Iterate through each char of hexVal

            // Copy each char of hexVal to commaSeperated
            commaSeperated += hexVal.charAt(i);

            // After each pair of characters add a comma, unless this
            // is the last char
            commaSeperated += (i % 2 == 1 && i != (hexVal.length - 1)) ? ',' : '';

        }

        // Lets now remove the 0x
        if(instr(commaSeperated, '0x'))
        {

            commaSeperated = commaSeperated.substr(4);

        }

        if(instr(commaSeperated, ','))
        {

            // Lets now remove all "," 's
            commaSeperated = commaSeperated.replace(/,/g, '');

            if( getwhich < 0 ) { getwhich = 0; }
            if( getwhich > 5 ) { getwhich = 5; }

            alpha   = [];
              red   = [];
            green   = [];
             blue   = [];
           allcol   = [];
           sixcol   = [];

           alpha[0] = commaSeperated[0]+commaSeperated[1];
             red[0] = commaSeperated[2]+commaSeperated[3];
           green[0] = commaSeperated[4]+commaSeperated[5];
            blue[0] = commaSeperated[6]+commaSeperated[7];
          allcol[0] =    alpha[0]+red[0]+green[0]+blue[0];
          sixcol[0] =             red[0]+green[0]+blue[0];

            if( getwhich === 0 ) { fi_string =  alpha[0]; }

            if( getwhich === 1 ) { fi_string =    red[0]; }
            if( getwhich === 2 ) { fi_string =  green[0]; }
            if( getwhich === 3 ) { fi_string =   blue[0]; }
            if( getwhich === 4 ) { fi_string = allcol[0]; }
            if( getwhich === 5 ) { fi_string = sixcol[0]; }

            if( getwhich === 4 && fi_string.length != 10 || fi_string.length != 9 ) { getwhich = 5; }
            if( getwhich === 5 && fi_string.length !=  8 || fi_string.length != 7 ) { getwhich = 4; }

            // Split the commaSeperated string by commas and return the array
            return fi_string.toString();

        }

    //}

}

function isArray(myArray)
{

    return myArray.constructor.toString();
    //myArray.constructor.toString().indexOf("Array") > -1;

}

//EntityMaterial(0, 0, 0xFF44CFFC, 1, 0xFF000000, 4, 4, 0, 1.0, 0.8, "LambertBasicMaterial", 1)
function EntityMaterial(ptex, side, color, wire, wirecolor, col_type, col_wire_type, shading, transparent, opacity, mat_type, overdraw)
{

    ptex = ptex || 0;

    side = side || 0;

    color = color || 0xFF006400;

    wire = wire || 0;

    wirecolor = wirecolor || 0xFF006400;

    col_type = col_type || 4;

    col_wire_type = col_wire_type || 4;

    shading = shading || false;

    transparent = transparent || 0.0;

    opacity = opacity || 1.0;

    mat_type = mat_type || "BasicMaterial";

    overdraw = overdraw || true;

    color = decToHex(color.toString());
    wirecolor = decToHex(wirecolor.toString());

    var gRGBA1 = Get_RGBA(color, col_type);
    var gRGBA2 = Get_RGBA(wirecolor, col_wire_type);

    var mat = 0;

    if(mat_type === 'BasicMaterial')
    {

        this.materials = new THREE.MeshBasicMaterial
        (

            {

                color: parseInt(gRGBA1, 16)

            }

        )

    }

    else if(mat_type === 'LambertMaterial')

    {

        this.materials = new THREE.MeshLambertMaterial
        (

            {

                color: parseInt(gRGBA2, 16), 
                opacity: opacity, 
                wireframe: wire, 
                transparent: transparent

            }

        )

    }

    else if(mat_type === 'LambertBasicMaterial')

    {

        //new empty array.. could also be written as this.materials = new Array();
        this.materials = [];

        var mats = this.materials;

            var basicMat       =     new THREE.MeshBasicMaterial( {   color: parseInt(gRGBA1, 16) } );
            var lambertMat     =   new THREE.MeshLambertMaterial( {   color: parseInt(gRGBA2, 16), opacity: opacity, wireframe: wire, transparent: transparent } );

            mats.push(basicMat);
            mats.push(lambertMat);

            api_messagebox(mats);

        return mats;

    }

}

非常感谢你!

此致,

〜Mythros

1 个答案:

答案 0 :(得分:0)

是的,我终于开始尝试了,这对我来说都很顺利。 为了确保我们在环境中没有任何差异,请查看我制作的小提琴,并告诉我它是否符合预期,或者如果您有任何其他问题需要帮助:

JSFiddle of original code

小变化:

注释掉了
api_messagebox(mats)

因为它未定义。 添加了大量日志语句,请查看Web控制台。


修改

我通过使用THree.js的Color对象修复了颜色问题,如下所示:

    var color = new THREE.Color("rgb(0,0,255)");

但是你可能会在某个地方这样做,因为你调用的GET_RGBA函数似乎从你给我的代码中遗漏了。

至于使它成为wiremesh,我检查了Lambert对象,它确实设置了wiremesh = 1

确保您传递的wire var实际设置为true,我在此更新的fiddle

中明确设置了它