📄 graytrace.h
字号:
/* Copyright (C) 2006, Mike Gashler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. see http://www.gnu.org/copyleft/lesser.html*/#ifndef __GRAYTRACE_H__#define __GRAYTRACE_H__#include <stdio.h>#include <math.h>#include "GArray.h"#include "GMacros.h"#include "GImage.h"class GRayTraceLight;class GRayTraceMaterial;class GRayTraceObject;class GRayTraceScene;class GRayTraceTriMesh;class GRayTraceBoundingBoxBase;class GPointerQueue;class GNodeHashTable;typedef float GRayTraceReal;// This class represents a color. It's more precise than GColor, but takes up more// memory. Note that the ray tracer ignores the alpha channel because the material// specifies a unique transmission color.class GRayTraceColor{public: GRayTraceReal a, r, g, b; GRayTraceColor() : a(1), r(0), g(0), b(0) { } GRayTraceColor(GRayTraceColor* pThat) { a = pThat->a; r = pThat->r; g = pThat->g; b = pThat->b; } GRayTraceColor(GColor c) { a = ((GRayTraceReal)gAlpha(c)) / 255; r = ((GRayTraceReal)gRed(c)) / 255; g = ((GRayTraceReal)gGreen(c)) / 255; b = ((GRayTraceReal)gBlue(c)) / 255; } GRayTraceColor(GRayTraceReal alpha, GRayTraceReal red, GRayTraceReal green, GRayTraceReal blue) { Set(alpha, red, green, blue); } bool IsBlack() { if(r == 0 && g == 0 && b == 0) return true; else return false; } void Set(GRayTraceReal alpha, GRayTraceReal red, GRayTraceReal green, GRayTraceReal blue) { a = alpha; r = red; g = green; b = blue; } void Set(GColor c) { a = ((GRayTraceReal)gAlpha(c)) / 255; r = ((GRayTraceReal)gRed(c)) / 255; g = ((GRayTraceReal)gGreen(c)) / 255; b = ((GRayTraceReal)gBlue(c)) / 255; } void Copy(GRayTraceColor* pThat) { a = pThat->a; r = pThat->r; g = pThat->g; b = pThat->b; } void Add(GRayTraceColor* pThat) { a = MAX(a, pThat->a); r += pThat->r; g += pThat->g; b += pThat->b; } void Clip() { r = MIN((GRayTraceReal)1, r); g = MIN((GRayTraceReal)1, g); b = MIN((GRayTraceReal)1, b); } void Multiply(GRayTraceReal mag) { r *= mag; g *= mag; b *= mag; } void Multiply(GRayTraceColor* pThat) { a *= pThat->a; r *= pThat->r; g *= pThat->g; b *= pThat->b; } GColor GetGColor() { return gARGB( MIN(255, (int)(a * 255)), MIN(255, (int)(r * 255)), MIN(255, (int)(g * 255)), MIN(255, (int)(b * 255)) ); }};class GRayTraceVector{public: GRayTraceReal m_vals[3]; GRayTraceVector() { m_vals[0] = 0; m_vals[1] = 0; m_vals[2] = 0; } GRayTraceVector(const GRayTraceVector* pThat) { m_vals[0] = pThat->m_vals[0]; m_vals[1] = pThat->m_vals[1]; m_vals[2] = pThat->m_vals[2]; } GRayTraceVector(GRayTraceReal x, GRayTraceReal y, GRayTraceReal z) { m_vals[0] = x; m_vals[1] = y; m_vals[2] = z; } void Copy(const GRayTraceVector* pThat) { m_vals[0] = pThat->m_vals[0]; m_vals[1] = pThat->m_vals[1]; m_vals[2] = pThat->m_vals[2]; } void Copy(GRayTraceReal x, GRayTraceReal y, GRayTraceReal z) { m_vals[0] = x; m_vals[1] = y; m_vals[2] = z; } void Set(GRayTraceReal x, GRayTraceReal y, GRayTraceReal z) { m_vals[0] = x; m_vals[1] = y; m_vals[2] = z; } inline void Normalize() { GRayTraceReal mag = (GRayTraceReal)sqrt(GetMagnitudeSquared()); m_vals[0] /= mag; m_vals[1] /= mag; m_vals[2] /= mag; } inline GRayTraceReal GetDistanceSquared(const GRayTraceVector* pThat) const { return (pThat->m_vals[0] - m_vals[0]) * (pThat->m_vals[0] - m_vals[0]) + (pThat->m_vals[1] - m_vals[1]) * (pThat->m_vals[1] - m_vals[1]) + (pThat->m_vals[2] - m_vals[2]) * (pThat->m_vals[2] - m_vals[2]); } inline double GetMagnitudeSquared() const { return (m_vals[0] * m_vals[0] + m_vals[1] * m_vals[1] + m_vals[2] * m_vals[2]); } inline void Add(const GRayTraceVector* pThat) { m_vals[0] += pThat->m_vals[0]; m_vals[1] += pThat->m_vals[1]; m_vals[2] += pThat->m_vals[2]; } inline void Add(GRayTraceReal mag, const GRayTraceVector* pThat) { m_vals[0] += mag * pThat->m_vals[0]; m_vals[1] += mag * pThat->m_vals[1]; m_vals[2] += mag * pThat->m_vals[2]; } inline void Subtract(const GRayTraceVector* pThat) { m_vals[0] -= pThat->m_vals[0]; m_vals[1] -= pThat->m_vals[1]; m_vals[2] -= pThat->m_vals[2]; } inline void Multiply(GRayTraceReal mag) { m_vals[0] *= mag; m_vals[1] *= mag; m_vals[2] *= mag; } inline GRayTraceReal DotProduct(const GRayTraceVector* pThat) { return m_vals[0] * pThat->m_vals[0] + m_vals[1] * pThat->m_vals[1] + m_vals[2] * pThat->m_vals[2]; } inline void CrossProduct(GRayTraceVector* pA, GRayTraceVector* pB) { m_vals[0] = pA->m_vals[1] * pB->m_vals[2] - pA->m_vals[2] * pB->m_vals[1]; m_vals[1] = pA->m_vals[2] * pB->m_vals[0] - pA->m_vals[0] * pB->m_vals[2]; m_vals[2] = pA->m_vals[0] * pB->m_vals[1] - pA->m_vals[1] * pB->m_vals[0]; } inline void ComputeTriangleNormal(const GRayTraceVector* pPoint1, const GRayTraceVector* pPoint2, const GRayTraceVector* pPoint3) { GRayTraceVector a(pPoint2); a.Subtract(pPoint1); GRayTraceVector b(pPoint3); b.Subtract(pPoint1); CrossProduct(&a, &b); Normalize(); } void ComputePlaneEquasion(const GRayTraceVector* pPoint1, const GRayTraceVector* pPoint2, const GRayTraceVector* pPoint3, GRayTraceReal* pOutD) { ComputeTriangleNormal(pPoint1, pPoint2, pPoint3); *pOutD = -(this->DotProduct(pPoint1)); } void ComputeReflectionVector(GRayTraceVector* pRay, GRayTraceVector* pNormal); // *pYaw and *pPitch are in radians inline void GetYawAndPitch(GRayTraceReal* pYaw, GRayTraceReal* pPitch) const { *pPitch = (GRayTraceReal)atan2(m_vals[1], sqrt(m_vals[0] * m_vals[0] + m_vals[2] * m_vals[2])); *pYaw = (GRayTraceReal)atan2(m_vals[0], m_vals[2]); if((*pYaw) < (-PI / 2)) (*pYaw) += (GRayTraceReal)(PI * 2); } // dYaw and dPitch are in radians inline void FromYawAndPitch(GRayTraceReal dYaw, GRayTraceReal dPitch) { m_vals[1] = (GRayTraceReal)sin(dPitch); double dTmp = (GRayTraceReal)cos(dPitch); m_vals[0] = (GRayTraceReal)(dTmp * sin(dYaw)); m_vals[2] = (GRayTraceReal)(dTmp * cos(dYaw)); } //inline double GetSimilarity(const Vector* pThat) const //{ // return( // (dX * pThat->dX + dY * pThat->dY + dZ * pThat->dZ) / // ( // sqrt(dX * dX + dY * dY + dZ * dZ) * // sqrt(pThat->dX * pThat->dX + pThat->dY * pThat->dY + pThat->dZ * pThat->dZ) // ) // ); //}};class GRayTraceCamera{protected: GRayTraceVector m_lookFromPoint; GRayTraceVector m_lookAtPoint; GRayTraceVector m_viewUpVector; GRayTraceVector m_viewSideVector; GRayTraceReal m_viewAngle; // in radians GRayTraceReal m_focalDistance; GRayTraceReal m_lensDiameter; int m_maxDepth; int m_nRaysPerPixel; int m_nWidth, m_nHeight;public: GRayTraceCamera() { m_lookFromPoint.Set(2, 0, 0); m_lookAtPoint.Set(0, 0, 0); m_viewUpVector.Set(0, 1, 0); m_viewAngle = (GRayTraceReal)(PI * 3 / 4); m_nRaysPerPixel = 1; m_maxDepth = 4; m_nWidth = 320; m_nHeight = 320; } ~GRayTraceCamera() { } void SetRoll(GRayTraceReal angle); void ComputeSideVector(); void SetRaysPerPixel(int n) { m_nRaysPerPixel = n; } GRayTraceVector* GetLookFromPoint() { return &m_lookFromPoint; } GRayTraceVector* GetLookAtPoint() { return &m_lookAtPoint; } GRayTraceVector* GetViewUpVector() { return &m_viewUpVector; } GRayTraceVector* GetViewSideVector() { return &m_viewSideVector; } void SetViewAngle(GRayTraceReal val) { m_viewAngle = val; } // This is the vertical view angle GRayTraceReal GetViewAngle() { return m_viewAngle; } void SetMaxDepth(int val) { m_maxDepth = val; } void SetImageSize(int width, int height) { m_nWidth = width; m_nHeight = height; } void SetFocalDistance(GRayTraceReal val) { m_focalDistance = val; } void SetLensDiameter(GRayTraceReal val) { m_lensDiameter = val; } inline int GetImageWidth() { return m_nWidth; } inline int GetImageHeight() { return m_nHeight; } inline int GetMaxDepth() { return m_maxDepth; } inline GRayTraceReal GetFocalDistance() { return m_focalDistance; } inline GRayTraceReal GetLensDiameter() { return m_lensDiameter; }};class GRayTraceRay{public: GRayTraceVector m_collisionPoint; GRayTraceVector m_normalVector; GRayTraceVector m_reflectionVector; GRayTraceColor m_color; GRayTraceReal m_indexOfRefraction; bool m_bHitTexture; GRayTraceReal m_textureX; GRayTraceReal m_textureY; GRayTraceRay(); GRayTraceRay(GRayTraceRay* pThat); ~GRayTraceRay(); void Cast(GRayTraceScene* pScene, GRayTraceVector* pRayOrigin, GRayTraceVector* pDirectionVector, int nMaxDepth); void Trace(GRayTraceScene* pScene, GRayTraceVector* pRayOrigin, GRayTraceVector* pDirectionVector, int nMaxDepth, bool bEmissive); void SetTextureCoords(GRayTraceReal x, GRayTraceReal y); void GetTextureCoords(GRayTraceReal* x, GRayTraceReal* y); bool DidRayHitTexture() { return m_bHitTexture; } static void JitterRay(GRayTraceVector* pVector, GRayTraceReal jitter);protected: bool ComputeTransmissionVector(GRayTraceVector* pDirectionVector, GRayTraceVector* pTransmissionVector, GRayTraceReal oldIndexOfRefraction, GRayTraceReal newIndexOfRefraction); void ComputeRandomDiffuseVector(GRayTraceVector* pOutVector);};class GRayTraceScene{public: enum RenderMode { FAST_RAY_TRACE, QUALITY_RAY_TRACE, PATH_TRACE, };protected: GRayTraceColor m_backgroundColor; GRayTraceColor m_ambientLight; GPointerArray* m_pMaterials; GPointerArray* m_pMeshes; GPointerArray* m_pObjects; GPointerArray* m_pLights; GRayTraceCamera* m_pCamera; GRayTraceBoundingBoxBase* m_pBoundingBoxTree; GRayTraceReal m_toneMappingConstant; // Rendering values
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -