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

📄 vector3.cpp

📁 WOW 服务模拟端 支持2.4.3版本 来自开源的ASCENT 自己REPACK
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**
 @file Vector3.cpp
 
 3D vector class
 
 @maintainer Morgan McGuire, matrix@graphics3d.com
 
 @cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
 
 @created 2001-06-02
 @edited  2006-01-30
 */

#include <limits>
#include <stdlib.h>
#include "G3D/Vector3.h"
#include "G3D/g3dmath.h"
#include "G3D/format.h"
#include "G3D/stringutils.h"
#include "G3D/Vector3int16.h"
#include "G3D/Matrix3.h"
#include "G3D/Vector2.h"
 
namespace G3D {

Vector3 Vector3::dummy;

// Deprecated.
const Vector3 Vector3::ZERO(0, 0, 0);
const Vector3 Vector3::ZERO3(0, 0, 0);
const Vector3 Vector3::UNIT_X(1, 0, 0);
const Vector3 Vector3::UNIT_Y(0, 1, 0);
const Vector3 Vector3::UNIT_Z(0, 0, 1);
const Vector3 Vector3::INF3((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf());
const Vector3 Vector3::NAN3((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan());

Vector3::Vector3(const class Vector2& v, float _z) : x(v.x), y(v.y), z(_z) {
}

Vector3::Axis Vector3::primaryAxis() const {
    
    Axis a = X_AXIS;

    double nx = abs(x);
    double ny = abs(y);
    double nz = abs(z);

    if (nx > ny) {
        if (nx > nz) {
            a = X_AXIS;
        } else {
            a = Z_AXIS;
        }
    } else {
        if (ny > nz) {
            a = Y_AXIS;
        } else {
            a = Z_AXIS;
        }
    }

    return a;
}


size_t Vector3::hashCode() const {
    size_t xhash = (*(size_t*)(void*)(&x));
    size_t yhash = (*(size_t*)(void*)(&y));
    size_t zhash = (*(size_t*)(void*)(&z));

    return xhash + (yhash * 37) + (zhash * 101);
}

std::ostream& operator<<(std::ostream& os, const Vector3& v) {
    return os << v.toString();
}


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

double frand() {
    return rand() / (double) RAND_MAX;
}


Vector3::Vector3(const class Vector3int16& v) {
    x = v.x;
    y = v.y;
    z = v.z;
}


Vector3 Vector3::random() {
    Vector3 result;

    do {
        result = Vector3(uniformRandom(-1.0, 1.0), 
                         uniformRandom(-1.0, 1.0),
                         uniformRandom(-1.0, 1.0));
    } while (result.squaredMagnitude() >= 1.0f);

    result.unitize();

    return result;
}

//----------------------------------------------------------------------------
Vector3 Vector3::operator/ (float fScalar) const {
    Vector3 kQuot;

    if ( fScalar != 0.0 ) {
		float fInvScalar = 1.0f / fScalar;
        kQuot.x = fInvScalar * x;
        kQuot.y = fInvScalar * y;
        kQuot.z = fInvScalar * z;
        return kQuot;
    } else {
        return Vector3::inf();
    }
}

//----------------------------------------------------------------------------
Vector3& Vector3::operator/= (float fScalar) {
    if (fScalar != 0.0) {
		float fInvScalar = 1.0f / fScalar;
        x *= fInvScalar;
        y *= fInvScalar;
        z *= fInvScalar;
    } else {
        x = (float)G3D::inf();
        y = (float)G3D::inf();
        z = (float)G3D::inf();
    }

    return *this;
}

//----------------------------------------------------------------------------
float Vector3::unitize (float fTolerance) {
	float fMagnitude = magnitude();

    if (fMagnitude > fTolerance) {
		float fInvMagnitude = 1.0f / fMagnitude;
        x *= fInvMagnitude;
        y *= fInvMagnitude;
        z *= fInvMagnitude;
    } else {
        fMagnitude = 0.0f;
    }

    return fMagnitude;
}

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

Vector3 Vector3::reflectAbout(const Vector3& normal) const {

    Vector3 out;

    Vector3 N = normal.direction();

    // 2 * normal.dot(this) * normal - this
    return N * 2 * this->dot(N) - *this;
}

//----------------------------------------------------------------------------
#if 0
Vector3 Vector3::cosRandom(const Vector3& normal) {
    double e1 = G3D::random(0, 1);
    double e2 = G3D::random(0, 1);

    // Angle from normal
    double theta = acos(sqrt(e1));

    // Angle about normal
    double phi   = 2 * G3D_PI * e2;

    // Make a coordinate system
    Vector3 U = normal.direction();
    Vector3 V = Vector3::unitX();

    if (abs(U.dot(V)) > .9) {
        V = Vector3::unitY();
    }

    Vector3 W = U.cross(V).direction();
    V = W.cross(U);

    // Convert to rectangular form
    return cos(theta) * U + sin(theta) * (cos(phi) * V + sin(phi) * W);
}
//----------------------------------------------------------------------------

Vector3 Vector3::hemiRandom(const Vector3& normal) {
    Vector3 V = Vector3::random();

    if (V.dot(normal) < 0) {
        return -V;
    } else {
        return V;
    }
}
#endif
//----------------------------------------------------------------------------

Vector3 Vector3::reflectionDirection(const Vector3& normal) const {
    return -reflectAbout(normal).direction();
}

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

Vector3 Vector3::refractionDirection(
    const Vector3&  normal,
    float           iInside,
    float           iOutside) const {

    // From pg. 24 of Henrik Wann Jensen. Realistic Image Synthesis
    // Using Photon Mapping.  AK Peters. ISBN: 1568811470. July 2001.

    // Invert the directions from Wann Jensen's formulation
    // and normalize the vectors.
    const Vector3 W = -direction();

⌨️ 快捷键说明

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