celx_vector.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:7k
- // celx_vector.cpp
- //
- // Copyright (C) 2003-2008, the Celestia Development Team
- //
- // Lua script extensions for Celestia: vector object
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public License
- // as published by the Free Software Foundation; either version 2
- // of the License, or (at your option) any later version.
- #include "celx.h"
- #include "celx_internal.h"
- #include "celx_vector.h"
- int vector_new(lua_State* l, const Vec3d& v)
- {
- CelxLua celx(l);
- Vec3d* v3 = reinterpret_cast<Vec3d*>(lua_newuserdata(l, sizeof(Vec3d)));
- *v3 = v;
- celx.setClass(Celx_Vec3);
-
- return 1;
- }
- Vec3d* to_vector(lua_State* l, int index)
- {
- CelxLua celx(l);
- return static_cast<Vec3d*>(celx.checkUserData(index, Celx_Vec3));
- }
- static Vec3d* this_vector(lua_State* l)
- {
- CelxLua celx(l);
- Vec3d* v3 = to_vector(l, 1);
- if (v3 == NULL)
- {
- celx.doError("Bad vector object!");
- }
-
- return v3;
- }
- static int vector_sub(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(2, 2, "Need two operands for sub");
- Vec3d* op1 = celx.toVector(1);
- Vec3d* op2 = celx.toVector(2);
- if (op1 == NULL || op2 == NULL)
- {
- celx.doError("Subtraction only defined for two vectors");
- }
- else
- {
- Vec3d result = *op1 - *op2;
- celx.newVector(result);
- }
- return 1;
- }
- static int vector_get(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(2, 2, "Invalid access of vector-component");
- Vec3d* v3 = this_vector(l);
- string key = celx.safeGetString(2, AllErrors, "Invalid key in vector-access");
- double value = 0.0;
- if (key == "x")
- value = v3->x;
- else if (key == "y")
- value = v3->y;
- else if (key == "z")
- value = v3->z;
- else
- {
- if (lua_getmetatable(l, 1))
- {
- lua_pushvalue(l, 2);
- lua_rawget(l, -2);
- return 1;
- }
- else
- {
- celx.doError("Internal error: couldn't get metatable");
- }
- }
- lua_pushnumber(l, (lua_Number)value);
- return 1;
- }
- static int vector_set(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(3, 3, "Invalid access of vector-component");
- Vec3d* v3 = this_vector(l);
- string key = celx.safeGetString(2, AllErrors, "Invalid key in vector-access");
- double value = celx.safeGetNumber(3, AllErrors, "Vector components must be numbers");
- if (key == "x")
- v3->x = value;
- else if (key == "y")
- v3->y = value;
- else if (key == "z")
- v3->z = value;
- else
- {
- celx.doError("Invalid key in vector-access");
- }
- return 0;
- }
- static int vector_getx(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(1, 1, "No arguments expected for vector:getx");
- Vec3d* v3 = this_vector(l);
- lua_Number x;
- x = static_cast<lua_Number>(v3->x);
- lua_pushnumber(l, x);
-
- return 1;
- }
- static int vector_gety(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(1, 1, "No arguments expected for vector:gety");
- Vec3d* v3 = this_vector(l);
- lua_Number y;
- y = static_cast<lua_Number>(v3->y);
- lua_pushnumber(l, y);
-
- return 1;
- }
- static int vector_getz(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(1, 1, "No arguments expected for vector:getz");
- Vec3d* v3 = this_vector(l);
- lua_Number z;
- z = static_cast<lua_Number>(v3->z);
- lua_pushnumber(l, z);
-
- return 1;
- }
- static int vector_normalize(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(1, 1, "No arguments expected for vector:normalize");
- Vec3d* v = this_vector(l);
- Vec3d vn(*v);
- vn.normalize();
- celx.newVector(vn);
- return 1;
- }
- static int vector_length(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(1, 1, "No arguments expected for vector:length");
- Vec3d* v = this_vector(l);
- double length = v->length();
- lua_pushnumber(l, (lua_Number)length);
- return 1;
- }
- static int vector_add(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(2, 2, "Need two operands for addition");
- Vec3d* v1 = NULL;
- Vec3d* v2 = NULL;
- UniversalCoord* p = NULL;
-
- if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
- {
- v1 = celx.toVector(1);
- v2 = celx.toVector(2);
- celx.newVector(*v1 + *v2);
- }
- else
- if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Position))
- {
- v1 = celx.toVector(1);
- p = celx.toPosition(2);
- celx.newPosition(*p + *v1);
- }
- else
- {
- celx.doError("Bad vector addition!");
- }
- return 1;
- }
- static int vector_mult(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(2, 2, "Need two operands for multiplication");
- Vec3d* v1 = NULL;
- Vec3d* v2 = NULL;
- Quatd* q = NULL;
- lua_Number s = 0.0;
- if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
- {
- v1 = celx.toVector(1);
- v2 = celx.toVector(2);
- lua_pushnumber(l, *v1 * *v2);
- }
- else
- if (celx.isType(1, Celx_Vec3) && lua_isnumber(l, 2))
- {
- v1 = celx.toVector(1);
- s = lua_tonumber(l, 2);
- celx.newVector(*v1 * s);
- }
- else
- if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Rotation))
- {
- v1 = celx.toVector(1);
- q = celx.toRotation(2);
- celx.newRotation(*v1 * *q);
- }
- else
- if (lua_isnumber(l, 1) && celx.isType(2, Celx_Vec3))
- {
- s = lua_tonumber(l, 1);
- v1 = celx.toVector(2);
- celx.newVector(*v1 * s);
- }
- else
- {
- celx.doError("Bad vector multiplication!");
- }
- return 1;
- }
- static int vector_cross(lua_State* l)
- {
- CelxLua celx(l);
- celx.checkArgs(2, 2, "Need two operands for multiplication");
- Vec3d* v1 = NULL;
- Vec3d* v2 = NULL;
- if (celx.isType(1, Celx_Vec3) && celx.isType(2, Celx_Vec3))
- {
- v1 = celx.toVector(1);
- v2 = celx.toVector(2);
- celx.newVector(*v1 ^ *v2);
- }
- else
- {
- celx.doError("Bad vector multiplication!");
- }
- return 1;
-
- }
- static int vector_tostring(lua_State* l)
- {
- lua_pushstring(l, "[Vector]");
- return 1;
- }
- void CreateVectorMetaTable(lua_State* l)
- {
- CelxLua celx(l);
- celx.createClassMetatable(Celx_Vec3);
-
- celx.registerMethod("__tostring", vector_tostring);
- celx.registerMethod("__add", vector_add);
- celx.registerMethod("__sub", vector_sub);
- celx.registerMethod("__mul", vector_mult);
- celx.registerMethod("__pow", vector_cross);
- celx.registerMethod("__index", vector_get);
- celx.registerMethod("__newindex", vector_set);
- celx.registerMethod("getx", vector_getx);
- celx.registerMethod("gety", vector_gety);
- celx.registerMethod("getz", vector_getz);
- celx.registerMethod("normalize", vector_normalize);
- celx.registerMethod("length", vector_length);
-
- lua_pop(l, 1); // remove metatable from stack
- }