mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-21 09:49:01 +00:00
VideoSW: reuse Common::Vec2/3/4
This commit is contained in:
parent
e6ed939952
commit
fa4127b145
8 changed files with 48 additions and 137 deletions
|
@ -643,7 +643,6 @@
|
||||||
<ClInclude Include="VideoBackends\Software\TextureEncoder.h" />
|
<ClInclude Include="VideoBackends\Software\TextureEncoder.h" />
|
||||||
<ClInclude Include="VideoBackends\Software\TextureSampler.h" />
|
<ClInclude Include="VideoBackends\Software\TextureSampler.h" />
|
||||||
<ClInclude Include="VideoBackends\Software\TransformUnit.h" />
|
<ClInclude Include="VideoBackends\Software\TransformUnit.h" />
|
||||||
<ClInclude Include="VideoBackends\Software\Vec3.h" />
|
|
||||||
<ClInclude Include="VideoBackends\Software\VideoBackend.h" />
|
<ClInclude Include="VideoBackends\Software\VideoBackend.h" />
|
||||||
<ClInclude Include="VideoBackends\Vulkan\CommandBufferManager.h" />
|
<ClInclude Include="VideoBackends\Vulkan\CommandBufferManager.h" />
|
||||||
<ClInclude Include="VideoBackends\Vulkan\Constants.h" />
|
<ClInclude Include="VideoBackends\Vulkan\Constants.h" />
|
||||||
|
|
|
@ -30,7 +30,6 @@ add_library(videosoftware
|
||||||
TextureSampler.h
|
TextureSampler.h
|
||||||
TransformUnit.cpp
|
TransformUnit.cpp
|
||||||
TransformUnit.h
|
TransformUnit.h
|
||||||
Vec3.h
|
|
||||||
VideoBackend.h
|
VideoBackend.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ enum
|
||||||
static inline int CalcClipMask(const OutputVertexData* v)
|
static inline int CalcClipMask(const OutputVertexData* v)
|
||||||
{
|
{
|
||||||
int cmask = 0;
|
int cmask = 0;
|
||||||
Vec4 pos = v->projectedPosition;
|
Common::Vec4 pos = v->projectedPosition;
|
||||||
|
|
||||||
if (pos.w - pos.x < 0)
|
if (pos.w - pos.x < 0)
|
||||||
cmask |= CLIP_POS_X_BIT;
|
cmask |= CLIP_POS_X_BIT;
|
||||||
|
@ -546,8 +546,8 @@ bool IsBackface(const OutputVertexData* v0, const OutputVertexData* v1, const Ou
|
||||||
|
|
||||||
void PerspectiveDivide(OutputVertexData* vertex)
|
void PerspectiveDivide(OutputVertexData* vertex)
|
||||||
{
|
{
|
||||||
Vec4& projected = vertex->projectedPosition;
|
Common::Vec4& projected = vertex->projectedPosition;
|
||||||
Vec3& screen = vertex->screenPosition;
|
Common::Vec3& screen = vertex->screenPosition;
|
||||||
|
|
||||||
float wInverse = 1.0f / projected.w;
|
float wInverse = 1.0f / projected.w;
|
||||||
screen.x = projected.x * wInverse * xfmem.viewport.wd + xfmem.viewport.xOrig;
|
screen.x = projected.x * wInverse * xfmem.viewport.wd + xfmem.viewport.xOrig;
|
||||||
|
|
|
@ -7,25 +7,17 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "VideoBackends/Software/Vec3.h"
|
#include "Common/Matrix.h"
|
||||||
|
|
||||||
struct Vec4
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float w;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InputVertexData
|
struct InputVertexData
|
||||||
{
|
{
|
||||||
u8 posMtx;
|
u8 posMtx;
|
||||||
std::array<u8, 8> texMtx;
|
std::array<u8, 8> texMtx;
|
||||||
|
|
||||||
Vec3 position;
|
Common::Vec3 position;
|
||||||
std::array<Vec3, 3> normal;
|
std::array<Common::Vec3, 3> normal;
|
||||||
std::array<std::array<u8, 4>, 2> color;
|
std::array<std::array<u8, 4>, 2> color;
|
||||||
std::array<std::array<float, 2>, 8> texCoords;
|
std::array<Common::Vec2, 8> texCoords;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OutputVertexData
|
struct OutputVertexData
|
||||||
|
@ -39,12 +31,12 @@ struct OutputVertexData
|
||||||
ALP_C
|
ALP_C
|
||||||
};
|
};
|
||||||
|
|
||||||
Vec3 mvPosition = {};
|
Common::Vec3 mvPosition = {};
|
||||||
Vec4 projectedPosition = {};
|
Common::Vec4 projectedPosition = {};
|
||||||
Vec3 screenPosition = {};
|
Common::Vec3 screenPosition = {};
|
||||||
std::array<Vec3, 3> normal{};
|
std::array<Common::Vec3, 3> normal{};
|
||||||
std::array<std::array<u8, 4>, 2> color{};
|
std::array<std::array<u8, 4>, 2> color{};
|
||||||
std::array<Vec3, 8> texCoords{};
|
std::array<Common::Vec3, 8> texCoords{};
|
||||||
|
|
||||||
void Lerp(float t, const OutputVertexData* a, const OutputVertexData* b)
|
void Lerp(float t, const OutputVertexData* a, const OutputVertexData* b)
|
||||||
{
|
{
|
||||||
|
|
|
@ -392,11 +392,12 @@ static void DrawTriangleFrontFace(const OutputVertexData* v0, const OutputVertex
|
||||||
|
|
||||||
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; i++)
|
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; i++)
|
||||||
{
|
{
|
||||||
for (int comp = 0; comp < 3; comp++)
|
TexSlopes[i][0] =
|
||||||
{
|
Slope(v0->texCoords[i].x * w[0], v1->texCoords[i].x * w[1], v2->texCoords[i].x * w[2], ctx);
|
||||||
TexSlopes[i][comp] = Slope(v0->texCoords[i][comp] * w[0], v1->texCoords[i][comp] * w[1],
|
TexSlopes[i][1] =
|
||||||
v2->texCoords[i][comp] * w[2], ctx);
|
Slope(v0->texCoords[i].y * w[0], v1->texCoords[i].y * w[1], v2->texCoords[i].y * w[2], ctx);
|
||||||
}
|
TexSlopes[i][2] =
|
||||||
|
Slope(v0->texCoords[i].z * w[0], v1->texCoords[i].z * w[1], v2->texCoords[i].z * w[2], ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Half-edge constants
|
// Half-edge constants
|
||||||
|
|
|
@ -200,42 +200,42 @@ void SWVertexLoader::ParseVertex(const PortableVertexDeclaration& vdec, int inde
|
||||||
m_cpu_vertex_buffer.data() + m_cpu_vertex_buffer.size());
|
m_cpu_vertex_buffer.data() + m_cpu_vertex_buffer.size());
|
||||||
src.Skip(index * vdec.stride);
|
src.Skip(index * vdec.stride);
|
||||||
|
|
||||||
ReadVertexAttribute<float>(&m_vertex.position[0], src, vdec.position, 0, 3, false);
|
ReadVertexAttribute<float>(&m_vertex.position.x, src, vdec.position, 0, 3, false);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < m_vertex.normal.size(); i++)
|
for (std::size_t i = 0; i < m_vertex.normal.size(); i++)
|
||||||
{
|
{
|
||||||
ReadVertexAttribute<float>(&m_vertex.normal[i][0], src, vdec.normals[i], 0, 3, false);
|
ReadVertexAttribute<float>(&m_vertex.normal[i].x, src, vdec.normals[i], 0, 3, false);
|
||||||
}
|
}
|
||||||
if (!vdec.normals[0].enable)
|
if (!vdec.normals[0].enable)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||||
m_vertex.normal[0][0] = vertex_shader_manager.constants.cached_normal[0];
|
m_vertex.normal[0].x = vertex_shader_manager.constants.cached_normal[0];
|
||||||
m_vertex.normal[0][1] = vertex_shader_manager.constants.cached_normal[1];
|
m_vertex.normal[0].y = vertex_shader_manager.constants.cached_normal[1];
|
||||||
m_vertex.normal[0][2] = vertex_shader_manager.constants.cached_normal[2];
|
m_vertex.normal[0].z = vertex_shader_manager.constants.cached_normal[2];
|
||||||
}
|
}
|
||||||
if (!vdec.normals[1].enable)
|
if (!vdec.normals[1].enable)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||||
m_vertex.normal[1][0] = vertex_shader_manager.constants.cached_tangent[0];
|
m_vertex.normal[1].x = vertex_shader_manager.constants.cached_tangent[0];
|
||||||
m_vertex.normal[1][1] = vertex_shader_manager.constants.cached_tangent[1];
|
m_vertex.normal[1].y = vertex_shader_manager.constants.cached_tangent[1];
|
||||||
m_vertex.normal[1][2] = vertex_shader_manager.constants.cached_tangent[2];
|
m_vertex.normal[1].z = vertex_shader_manager.constants.cached_tangent[2];
|
||||||
}
|
}
|
||||||
if (!vdec.normals[2].enable)
|
if (!vdec.normals[2].enable)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
auto& vertex_shader_manager = system.GetVertexShaderManager();
|
||||||
m_vertex.normal[2][0] = vertex_shader_manager.constants.cached_binormal[0];
|
m_vertex.normal[2].x = vertex_shader_manager.constants.cached_binormal[0];
|
||||||
m_vertex.normal[2][1] = vertex_shader_manager.constants.cached_binormal[1];
|
m_vertex.normal[2].y = vertex_shader_manager.constants.cached_binormal[1];
|
||||||
m_vertex.normal[2][2] = vertex_shader_manager.constants.cached_binormal[2];
|
m_vertex.normal[2].z = vertex_shader_manager.constants.cached_binormal[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseColorAttributes(&m_vertex, src, vdec);
|
ParseColorAttributes(&m_vertex, src, vdec);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < m_vertex.texCoords.size(); i++)
|
for (std::size_t i = 0; i < m_vertex.texCoords.size(); i++)
|
||||||
{
|
{
|
||||||
ReadVertexAttribute<float>(m_vertex.texCoords[i].data(), src, vdec.texcoords[i], 0, 2, false);
|
ReadVertexAttribute<float>(&m_vertex.texCoords[i].x, src, vdec.texcoords[i], 0, 2, false);
|
||||||
|
|
||||||
// the texmtr is stored as third component of the texCoord
|
// the texmtr is stored as third component of the texCoord
|
||||||
if (vdec.texcoords[i].components >= 3)
|
if (vdec.texcoords[i].components >= 3)
|
||||||
|
|
|
@ -11,17 +11,21 @@
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Common/Matrix.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Common/Swap.h"
|
#include "Common/Swap.h"
|
||||||
|
|
||||||
#include "VideoBackends/Software/NativeVertexFormat.h"
|
#include "VideoBackends/Software/NativeVertexFormat.h"
|
||||||
#include "VideoBackends/Software/Vec3.h"
|
|
||||||
|
|
||||||
#include "VideoCommon/BPMemory.h"
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/XFMemory.h"
|
#include "VideoCommon/XFMemory.h"
|
||||||
|
|
||||||
namespace TransformUnit
|
namespace TransformUnit
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using Vec3 = Common::Vec3;
|
||||||
|
using Vec4 = Common::Vec4;
|
||||||
|
|
||||||
static void MultiplyVec2Mat24(const Vec3& vec, const float* mat, Vec3& result)
|
static void MultiplyVec2Mat24(const Vec3& vec, const float* mat, Vec3& result)
|
||||||
{
|
{
|
||||||
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
|
result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
|
||||||
|
@ -102,7 +106,7 @@ void TransformNormal(const InputVertexData* src, OutputVertexData* dst)
|
||||||
// By normalising the first transformed normal (which is used by lighting calculations and needs
|
// By normalising the first transformed normal (which is used by lighting calculations and needs
|
||||||
// to be unit length), the same transform matrix can do double duty, scaling for emboss mapping,
|
// to be unit length), the same transform matrix can do double duty, scaling for emboss mapping,
|
||||||
// and not scaling for lighting.
|
// and not scaling for lighting.
|
||||||
dst->normal[0].Normalize();
|
dst->normal[0] = dst->normal[0].Normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TransformTexCoordRegular(const TexMtxInfo& texinfo, int coordNum,
|
static void TransformTexCoordRegular(const TexMtxInfo& texinfo, int coordNum,
|
||||||
|
@ -127,8 +131,8 @@ static void TransformTexCoordRegular(const TexMtxInfo& texinfo, int coordNum,
|
||||||
{
|
{
|
||||||
ASSERT(texinfo.sourcerow >= SourceRow::Tex0 && texinfo.sourcerow <= SourceRow::Tex7);
|
ASSERT(texinfo.sourcerow >= SourceRow::Tex0 && texinfo.sourcerow <= SourceRow::Tex7);
|
||||||
u32 texnum = static_cast<u32>(texinfo.sourcerow.Value()) - static_cast<u32>(SourceRow::Tex0);
|
u32 texnum = static_cast<u32>(texinfo.sourcerow.Value()) - static_cast<u32>(SourceRow::Tex0);
|
||||||
src.x = srcVertex->texCoords[texnum][0];
|
src.x = srcVertex->texCoords[texnum].x;
|
||||||
src.y = srcVertex->texCoords[texnum][1];
|
src.y = srcVertex->texCoords[texnum].y;
|
||||||
src.z = 1.0f;
|
src.z = 1.0f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -228,22 +232,22 @@ static float CalculateLightAttn(const LightPointer* light, Vec3* _ldir, const Ve
|
||||||
case AttenuationFunc::Spec:
|
case AttenuationFunc::Spec:
|
||||||
{
|
{
|
||||||
ldir = ldir.Normalized();
|
ldir = ldir.Normalized();
|
||||||
attn = (ldir * normal) >= 0.0 ? std::max(0.0f, light->dir * normal) : 0;
|
attn = ldir.Dot(normal) >= 0.0 ? std::max(0.0f, light->dir.Dot(normal)) : 0;
|
||||||
Vec3 attLen = Vec3(1.0, attn, attn * attn);
|
Vec3 attLen = Vec3(1.0, attn, attn * attn);
|
||||||
Vec3 cosAttn = light->cosatt;
|
Vec3 cosAttn = light->cosatt;
|
||||||
Vec3 distAttn = light->distatt;
|
Vec3 distAttn = light->distatt;
|
||||||
if (chan.diffusefunc != DiffuseFunc::None)
|
if (chan.diffusefunc != DiffuseFunc::None)
|
||||||
distAttn = distAttn.Normalized();
|
distAttn = distAttn.Normalized();
|
||||||
|
|
||||||
attn = SafeDivide(std::max(0.0f, attLen * cosAttn), attLen * distAttn);
|
attn = SafeDivide(std::max(0.0f, attLen.Dot(cosAttn)), attLen.Dot(distAttn));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AttenuationFunc::Spot:
|
case AttenuationFunc::Spot:
|
||||||
{
|
{
|
||||||
float dist2 = ldir.Length2();
|
float dist2 = ldir.LengthSquared();
|
||||||
float dist = sqrtf(dist2);
|
float dist = sqrtf(dist2);
|
||||||
ldir = ldir / dist;
|
ldir = ldir / dist;
|
||||||
attn = std::max(0.0f, ldir * light->dir);
|
attn = std::max(0.0f, ldir.Dot(light->dir));
|
||||||
|
|
||||||
float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
|
float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
|
||||||
float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
|
float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
|
||||||
|
@ -265,7 +269,7 @@ static void LightColor(const Vec3& pos, const Vec3& normal, u8 lightNum, const L
|
||||||
Vec3 ldir = light->pos - pos;
|
Vec3 ldir = light->pos - pos;
|
||||||
float attn = CalculateLightAttn(light, &ldir, normal, chan);
|
float attn = CalculateLightAttn(light, &ldir, normal, chan);
|
||||||
|
|
||||||
float difAttn = ldir * normal;
|
float difAttn = ldir.Dot(normal);
|
||||||
switch (chan.diffusefunc)
|
switch (chan.diffusefunc)
|
||||||
{
|
{
|
||||||
case DiffuseFunc::None:
|
case DiffuseFunc::None:
|
||||||
|
@ -291,7 +295,7 @@ static void LightAlpha(const Vec3& pos, const Vec3& normal, u8 lightNum, const L
|
||||||
Vec3 ldir = light->pos - pos;
|
Vec3 ldir = light->pos - pos;
|
||||||
float attn = CalculateLightAttn(light, &ldir, normal, chan);
|
float attn = CalculateLightAttn(light, &ldir, normal, chan);
|
||||||
|
|
||||||
float difAttn = ldir * normal;
|
float difAttn = ldir.Dot(normal);
|
||||||
switch (chan.diffusefunc)
|
switch (chan.diffusefunc)
|
||||||
{
|
{
|
||||||
case DiffuseFunc::None:
|
case DiffuseFunc::None:
|
||||||
|
@ -412,8 +416,8 @@ void TransformTexCoord(const InputVertexData* src, OutputVertexData* dst)
|
||||||
const LightPointer* light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift];
|
const LightPointer* light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift];
|
||||||
|
|
||||||
Vec3 ldir = (light->pos - dst->mvPosition).Normalized();
|
Vec3 ldir = (light->pos - dst->mvPosition).Normalized();
|
||||||
float d1 = ldir * dst->normal[1];
|
float d1 = ldir.Dot(dst->normal[1]);
|
||||||
float d2 = ldir * dst->normal[2];
|
float d2 = ldir.Dot(dst->normal[2]);
|
||||||
|
|
||||||
dst->texCoords[coordNum].x = dst->texCoords[texinfo.embosssourceshift].x + d1;
|
dst->texCoords[coordNum].x = dst->texCoords[texinfo.embosssourceshift].x + d1;
|
||||||
dst->texCoords[coordNum].y = dst->texCoords[texinfo.embosssourceshift].y + d2;
|
dst->texCoords[coordNum].y = dst->texCoords[texinfo.embosssourceshift].y + d2;
|
||||||
|
@ -440,8 +444,8 @@ void TransformTexCoord(const InputVertexData* src, OutputVertexData* dst)
|
||||||
|
|
||||||
for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
|
for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
|
||||||
{
|
{
|
||||||
dst->texCoords[coordNum][0] *= (bpmem.texcoords[coordNum].s.scale_minus_1 + 1);
|
dst->texCoords[coordNum].x *= bpmem.texcoords[coordNum].s.scale_minus_1 + 1;
|
||||||
dst->texCoords[coordNum][1] *= (bpmem.texcoords[coordNum].t.scale_minus_1 + 1);
|
dst->texCoords[coordNum].y *= bpmem.texcoords[coordNum].t.scale_minus_1 + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace TransformUnit
|
} // namespace TransformUnit
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
// Copyright 2010 Dolphin Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
class Vec3
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
float x, y, z;
|
|
||||||
|
|
||||||
Vec3() = default;
|
|
||||||
explicit Vec3(float f) { x = y = z = f; }
|
|
||||||
explicit Vec3(const float* f)
|
|
||||||
{
|
|
||||||
x = f[0];
|
|
||||||
y = f[1];
|
|
||||||
z = f[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3(const float _x, const float _y, const float _z)
|
|
||||||
{
|
|
||||||
x = _x;
|
|
||||||
y = _y;
|
|
||||||
z = _z;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(const float _x, const float _y, const float _z)
|
|
||||||
{
|
|
||||||
x = _x;
|
|
||||||
y = _y;
|
|
||||||
z = _z;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3 operator+(const Vec3& other) const { return Vec3(x + other.x, y + other.y, z + other.z); }
|
|
||||||
void operator+=(const Vec3& other)
|
|
||||||
{
|
|
||||||
x += other.x;
|
|
||||||
y += other.y;
|
|
||||||
z += other.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3 operator-(const Vec3& v) const { return Vec3(x - v.x, y - v.y, z - v.z); }
|
|
||||||
void operator-=(const Vec3& other)
|
|
||||||
{
|
|
||||||
x -= other.x;
|
|
||||||
y -= other.y;
|
|
||||||
z -= other.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3 operator-() const { return Vec3(-x, -y, -z); }
|
|
||||||
Vec3 operator*(const float f) const { return Vec3(x * f, y * f, z * f); }
|
|
||||||
Vec3 operator/(const float f) const
|
|
||||||
{
|
|
||||||
float invf = (1.0f / f);
|
|
||||||
return Vec3(x * invf, y * invf, z * invf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator/=(const float f) { *this = *this / f; }
|
|
||||||
float operator*(const Vec3& other) const { return (x * other.x) + (y * other.y) + (z * other.z); }
|
|
||||||
void operator*=(const float f) { *this = *this * f; }
|
|
||||||
Vec3 ScaledBy(const Vec3& other) const { return Vec3(x * other.x, y * other.y, z * other.z); }
|
|
||||||
Vec3 operator%(const Vec3& v) const
|
|
||||||
{
|
|
||||||
return Vec3((y * v.z) - (z * v.y), (z * v.x) - (x * v.z), (x * v.y) - (y * v.x));
|
|
||||||
}
|
|
||||||
|
|
||||||
float Length2() const { return (x * x) + (y * y) + (z * z); }
|
|
||||||
float Length() const { return sqrtf(Length2()); }
|
|
||||||
float Distance2To(Vec3& other) { return (other - (*this)).Length2(); }
|
|
||||||
Vec3 Normalized() const { return (*this) / Length(); }
|
|
||||||
void Normalize() { (*this) /= Length(); }
|
|
||||||
float& operator[](int i) { return *((&x) + i); }
|
|
||||||
float operator[](const int i) const { return *((&x) + i); }
|
|
||||||
bool operator==(const Vec3& other) const { return x == other.x && y == other.y && z == other.z; }
|
|
||||||
void SetZero()
|
|
||||||
{
|
|
||||||
x = 0.0f;
|
|
||||||
y = 0.0f;
|
|
||||||
z = 0.0f;
|
|
||||||
}
|
|
||||||
};
|
|
Loading…
Add table
Add a link
Reference in a new issue