mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 09:01:57 -05:00
WIP on picking from arbitary coordinates instead of screen centre
This commit is contained in:
parent
5801e7888d
commit
26eab7ff03
5 changed files with 87 additions and 14 deletions
30
src/Chat.c
30
src/Chat.c
|
@ -424,10 +424,24 @@ static void ResolutionCommand_Execute(const cc_string* args, int argsCount) {
|
|||
} else if (width <= 0 || height <= 0) {
|
||||
Chat_AddRaw("&e/client: &cWidth and height must be above 0.");
|
||||
} else {
|
||||
Window_SetSize(width, height);
|
||||
/* Window_Create uses these, but scales by DPI. Hence DPI unscale them here. */
|
||||
Options_SetInt(OPT_WINDOW_WIDTH, (int)(width / DisplayInfo.ScaleX));
|
||||
Options_SetInt(OPT_WINDOW_HEIGHT, (int)(height / DisplayInfo.ScaleY));
|
||||
struct Matrix mvp, inv;
|
||||
struct Vec4 output;
|
||||
Vec3 input;
|
||||
Matrix_Mul(&mvp, &Gfx.View, &Gfx.Projection);
|
||||
Matrix_Invert(&inv, &mvp);
|
||||
|
||||
input.X = width;
|
||||
input.Y = height;
|
||||
input.Z = 0;
|
||||
input.Y = Game.Height - input.Y - 1;
|
||||
|
||||
input.X = (2 * input.X) / Game.Width - 1;
|
||||
input.Y = (2 * input.Y) / Game.Height - 1;
|
||||
input.Z = 2 * input.Z - 1;
|
||||
|
||||
Vec4_Transform(&output, &input, &inv);
|
||||
output.X /= output.W; output.Y /= output.W; output.Z /= output.W;
|
||||
Chat_Add3("VEC: %f3, %f3, %f3", &output.X, &output.Y, &output.Z);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,15 +454,11 @@ static struct ChatCommand ResolutionCommand = {
|
|||
};
|
||||
|
||||
static void ModelCommand_Execute(const cc_string* args, int argsCount) {
|
||||
if (argsCount) {
|
||||
Entity_SetModel(&LocalPlayer_Instance.Base, &args[0]);
|
||||
} else {
|
||||
Chat_AddRaw("&e/client model: &cYou didn't specify a model name.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static struct ChatCommand ModelCommand = {
|
||||
"Model", ModelCommand_Execute, true,
|
||||
"Model", ModelCommand_Execute, false,
|
||||
{
|
||||
"&a/client model [name]",
|
||||
"&bnames: &echibi, chicken, creeper, human, pig, sheep",
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "Protocol.h"
|
||||
#include "AxisLinesRenderer.h"
|
||||
#include "Picking.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
static cc_bool input_buttonsDown[3];
|
||||
static int input_pickingId = -1;
|
||||
|
@ -872,9 +873,7 @@ static cc_bool HandleNonClassicKey(int key) {
|
|||
" &eAxis lines (&4X&e, &2Y&e, &1Z&e) now show",
|
||||
" &eAxis lines no longer show");
|
||||
} else if (key == KeyBinds[KEYBIND_AUTOROTATE]) {
|
||||
InputHandler_Toggle(key, &AutoRotate_Enabled,
|
||||
" &eAuto rotate is &aenabled",
|
||||
" &eAuto rotate is &cdisabled");
|
||||
|
||||
} else if (key == KeyBinds[KEYBIND_THIRD_PERSON]) {
|
||||
Camera_CycleActive();
|
||||
} else if (key == KeyBinds[KEYBIND_DROP_BLOCK]) {
|
||||
|
|
|
@ -107,7 +107,7 @@ static int Program_Run(int argc, char** argv) {
|
|||
#ifdef _MSC_VER
|
||||
/* NOTE: Make sure to comment this out before pushing a commit */
|
||||
//cc_string rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565");
|
||||
//cc_string rawArgs = String_FromConst("UnknownShadow200");
|
||||
// rawArgs = String_FromConst("UnknownShadow200");
|
||||
//argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -26,6 +26,15 @@ void Vec3_Transform(Vec3* result, const Vec3* a, const struct Matrix* mat) {
|
|||
result->X = x; result->Y = y; result->Z = z;
|
||||
}
|
||||
|
||||
void Vec4_Transform(struct Vec4* result, const Vec3* a, const struct Matrix* mat) {
|
||||
/* a could be pointing to result - therefore can't directly assign X/Y/Z */
|
||||
float x = a->X * mat->row1.X + a->Y * mat->row2.X + a->Z * mat->row3.X + mat->row4.X;
|
||||
float y = a->X * mat->row1.Y + a->Y * mat->row2.Y + a->Z * mat->row3.Y + mat->row4.Y;
|
||||
float z = a->X * mat->row1.Z + a->Y * mat->row2.Z + a->Z * mat->row3.Z + mat->row4.Z;
|
||||
float w = a->X * mat->row1.W + a->Y * mat->row2.W + a->Z * mat->row3.W + mat->row4.W;
|
||||
result->X = x; result->Y = y; result->Z = z; result->W = w;
|
||||
}
|
||||
|
||||
void Vec3_TransformY(Vec3* result, float y, const struct Matrix* mat) {
|
||||
result->X = y * mat->row2.X + mat->row4.X;
|
||||
result->Y = y * mat->row2.Y + mat->row4.Y;
|
||||
|
@ -167,6 +176,59 @@ void Matrix_Mul(struct Matrix* result, const struct Matrix* left, const struct M
|
|||
result->row4.W = (((lM41 * rM14) + (lM42 * rM24)) + (lM43 * rM34)) + (lM44 * rM44);
|
||||
}
|
||||
|
||||
void Matrix_Invert(struct Matrix* dst, const struct Matrix* m) {
|
||||
/* https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix */
|
||||
/* https://stackoverflow.com/questions/18244678/3d-ray-picking-use-mouse-coordinates-when-mouse-isnt-locked */
|
||||
/* https://dondi.lmu.build/share/cg/unproject-explained.pdf */
|
||||
/* Have to use double for precision reasons */
|
||||
double det;
|
||||
double A23_23 = m->row3.Z * m->row4.W - m->row3.W * m->row4.Z;
|
||||
double A13_23 = m->row3.Y * m->row4.W - m->row3.W * m->row4.Y;
|
||||
double A12_23 = m->row3.Y * m->row4.Z - m->row3.Z * m->row4.Y;
|
||||
double A03_23 = m->row3.X * m->row4.W - m->row3.W * m->row4.X;
|
||||
double A02_23 = m->row3.X * m->row4.Z - m->row3.Z * m->row4.X;
|
||||
double A01_23 = m->row3.X * m->row4.Y - m->row3.Y * m->row4.X;
|
||||
double A23_13 = m->row2.Z * m->row4.W - m->row2.W * m->row4.Z;
|
||||
double A13_13 = m->row2.Y * m->row4.W - m->row2.W * m->row4.Y;
|
||||
double A12_13 = m->row2.Y * m->row4.Z - m->row2.Z * m->row4.Y;
|
||||
double A23_12 = m->row2.Z * m->row3.W - m->row2.W * m->row3.Z;
|
||||
double A13_12 = m->row2.Y * m->row3.W - m->row2.W * m->row3.Y;
|
||||
double A12_12 = m->row2.Y * m->row3.Z - m->row2.Z * m->row3.Y;
|
||||
double A03_13 = m->row2.X * m->row4.W - m->row2.W * m->row4.X;
|
||||
double A02_13 = m->row2.X * m->row4.Z - m->row2.Z * m->row4.X;
|
||||
double A03_12 = m->row2.X * m->row3.W - m->row2.W * m->row3.X;
|
||||
double A02_12 = m->row2.X * m->row3.Z - m->row2.Z * m->row3.X;
|
||||
double A01_13 = m->row2.X * m->row4.Y - m->row2.Y * m->row4.X;
|
||||
double A01_12 = m->row2.X * m->row3.Y - m->row2.Y * m->row3.X;
|
||||
|
||||
det =
|
||||
m->row1.X * (m->row2.Y * A23_23 - m->row2.Z * A13_23 + m->row2.W * A12_23)
|
||||
- m->row1.Y * (m->row2.X * A23_23 - m->row2.Z * A03_23 + m->row2.W * A02_23)
|
||||
+ m->row1.Z * (m->row2.X * A13_23 - m->row2.Y * A03_23 + m->row2.W * A01_23)
|
||||
- m->row1.W * (m->row2.X * A12_23 - m->row2.Y * A02_23 + m->row2.Z * A01_23);
|
||||
det = 1.0 / det;
|
||||
|
||||
dst->row1.X = (float)(det * (m->row2.Y * A23_23 - m->row2.Z * A13_23 + m->row2.W * A12_23));
|
||||
dst->row1.Y = (float)(det * -(m->row1.Y * A23_23 - m->row1.Z * A13_23 + m->row1.W * A12_23));
|
||||
dst->row1.Z = (float)(det * (m->row1.Y * A23_13 - m->row1.Z * A13_13 + m->row1.W * A12_13));
|
||||
dst->row1.W = (float)(det * -(m->row1.Y * A23_12 - m->row1.Z * A13_12 + m->row1.W * A12_12));
|
||||
|
||||
dst->row2.X = (float)(det * -(m->row2.X * A23_23 - m->row2.Z * A03_23 + m->row2.W * A02_23));
|
||||
dst->row2.Y = (float)(det * (m->row1.X * A23_23 - m->row1.Z * A03_23 + m->row1.W * A02_23));
|
||||
dst->row2.Z = (float)(det * -(m->row1.X * A23_13 - m->row1.Z * A03_13 + m->row1.W * A02_13));
|
||||
dst->row2.W = (float)(det * (m->row1.X * A23_12 - m->row1.Z * A03_12 + m->row1.W * A02_12));
|
||||
|
||||
dst->row3.X = (float)(det * (m->row2.X * A13_23 - m->row2.Y * A03_23 + m->row2.W * A01_23));
|
||||
dst->row3.Y = (float)(det * -(m->row1.X * A13_23 - m->row1.Y * A03_23 + m->row1.W * A01_23));
|
||||
dst->row3.Z = (float)(det * (m->row1.X * A13_13 - m->row1.Y * A03_13 + m->row1.W * A01_13));
|
||||
dst->row3.W = (float)(det * -(m->row1.X * A13_12 - m->row1.Y * A03_12 + m->row1.W * A01_12));
|
||||
|
||||
dst->row4.X = (float)(det * -(m->row2.X * A12_23 - m->row2.Y * A02_23 + m->row2.Z * A01_23));
|
||||
dst->row4.Y = (float)(det * (m->row1.X * A12_23 - m->row1.Y * A02_23 + m->row1.Z * A01_23));
|
||||
dst->row4.Z = (float)(det * -(m->row1.X * A12_13 - m->row1.Y * A02_13 + m->row1.Z * A01_13));
|
||||
dst->row4.W = (float)(det * (m->row1.X * A12_12 - m->row1.Y * A02_12 + m->row1.Z * A01_12));
|
||||
}
|
||||
|
||||
void Matrix_Orthographic(struct Matrix* result, float left, float right, float top, float bottom, float zNear, float zFar) {
|
||||
/* Transposed, source https://msdn.microsoft.com/en-us/library/dd373965(v=vs.85).aspx */
|
||||
*result = Matrix_Identity;
|
||||
|
|
|
@ -81,6 +81,7 @@ void Vec3_Normalize(Vec3* result, const Vec3* a);
|
|||
|
||||
/* Transforms a vector by the given matrix. */
|
||||
void Vec3_Transform(Vec3* result, const Vec3* a, const struct Matrix* mat);
|
||||
void Vec4_Transform(struct Vec4* result, const Vec3* a, const struct Matrix* mat);
|
||||
/* Same as Vec3_Transform, but faster since X and Z are assumed as 0. */
|
||||
void Vec3_TransformY(Vec3* result, float y, const struct Matrix* mat);
|
||||
|
||||
|
@ -120,6 +121,7 @@ CC_API void Matrix_Scale(struct Matrix* result, float x, float y, float z);
|
|||
/* Multiplies two matrices together. */
|
||||
/* NOTE: result can be the same pointer as left or right. */
|
||||
CC_API void Matrix_Mul(struct Matrix* result, const struct Matrix* left, const struct Matrix* right);
|
||||
void Matrix_Invert(struct Matrix* dst, const struct Matrix* m);
|
||||
|
||||
void Matrix_Orthographic(struct Matrix* result, float left, float right, float top, float bottom, float zNear, float zFar);
|
||||
void Matrix_PerspectiveFieldOfView(struct Matrix* result, float fovy, float aspect, float zNear, float zFar);
|
||||
|
|
Loading…
Reference in a new issue