void DebugEmitterComponent::_CalculateNodeTransform(std::stack<mat4*>& stack, mat4* res) { if (stack.size() == 1) { auto top = stack.top(); stack.pop(); mat4 result; mat4_copy(result, *top); mat4_copy(*res, result); float a = 0; } else { mat4 childRes; auto top = stack.top(); stack.pop(); _CalculateNodeTransform(stack, &childRes); mat4 result; mat4_mul_mat4(*top, childRes, result); mat4_copy(*res, result); float a = 0; } }
void MatrixMultiplyShear(mat4_t m, vec_t x, vec_t y) { mat4_t tmp, shear; mat4_copy(m, tmp); MatrixSetupShear(shear, x, y); mat4_mult(tmp, shear, m); }
void MatrixMultiplyZRotation(mat4_t m, vec_t degrees) { mat4_t tmp, rot; mat4_copy(m, tmp); MatrixSetupZRotation(rot, degrees); mat4_mult(tmp, rot, m); }
static int on_move(gesture3d_t *gest, void *user) { float face_plane[4][4]; cursor_t *curs = gest->cursor; tool_move_t *tool = user; float n[3], pos[3], d[3], ofs[3], v[3]; layer_t *layer = goxel->image->active_layer; float mat[4][4]; if (box_is_null(tool->box)) return GESTURE_FAILED; if (gest->type == GESTURE_HOVER) { goxel_set_help_text(goxel, "Drag to move face"); if (curs->snaped != SNAP_LAYER_OUT) return GESTURE_FAILED; tool->snap_face = get_face(curs->normal); curs->snap_offset = 0; curs->snap_mask &= ~SNAP_ROUNDED; mat4_mul(tool->box, FACES_MATS[tool->snap_face], face_plane); render_img(&goxel->rend, NULL, face_plane, EFFECT_NO_SHADING); if (curs->flags & CURSOR_PRESSED) { gest->type = GESTURE_DRAG; vec3_normalize(face_plane[0], v); plane_from_vectors(goxel->tool_plane, curs->pos, curs->normal, v); image_history_push(goxel->image); } return 0; } if (gest->type == GESTURE_DRAG) { goxel_set_help_text(goxel, "Drag to move face"); curs->snap_offset = 0; curs->snap_mask &= ~SNAP_ROUNDED; mat4_mul(tool->box, FACES_MATS[tool->snap_face], face_plane); vec3_normalize(face_plane[2], n); vec3_sub(curs->pos, goxel->tool_plane[3], v); vec3_project(v, n, v); vec3_add(goxel->tool_plane[3], v, pos); pos[0] = round(pos[0]); pos[1] = round(pos[1]); pos[2] = round(pos[2]); vec3_add(tool->box[3], face_plane[2], d); vec3_sub(pos, d, ofs); vec3_project(ofs, n, ofs); mat4_set_identity(mat); mat4_itranslate(mat, ofs[0], ofs[1], ofs[2]); do_move(layer, mat); if (gest->state == GESTURE_END) { gest->type = GESTURE_HOVER; mat4_copy(plane_null, goxel->tool_plane); } return 0; } return 0; }
void GL_LoadProjectionMatrix(const mat4_t m) { if (mat4_compare(GLSTACK_PM, m)) { return; } mat4_copy(m, GLSTACK_PM); mat4_mult(GLSTACK_PM, GLSTACK_MVM, GLSTACK_MVPM); }
void GL_LoadModelViewMatrix(const mat4_t m) { if (mat4_compare(GLSTACK_MVM, m)) { return; } mat4_copy(m, GLSTACK_MVM); mat4_mult(GLSTACK_PM, GLSTACK_MVM, GLSTACK_MVPM); }
void mat4_rotateY(mat4 m, float theta) { mat4 transform = { cosf(theta), 0, sinf(theta), 0, 0, 1, 0, 0, -sinf(theta), 0, cosf(theta), 0, 0, 0, 0, 1 }; mat4 tmp; mat4_multiply(m, transform, tmp); mat4_copy(m, tmp); }
void mat4_translate(mat4 m, float x, float y, float z) { mat4 transform = { 1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1 }; mat4 tmp; mat4_multiply(m, transform, tmp); mat4_copy(m, tmp); }
void mat4_mult(mat4_t mat1, mat4_t mat2) { int x, y; float mat1t[16]; mat4_copy(mat1t, mat1); for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { mat1[y*4+x] = mat1t[y*4+0] * mat2[x+0] + mat1t[y*4+1] * mat2[x+4] + mat1t[y*4+2] * mat2[x+8] + mat1t[y*4+3] * mat2[x+12]; } } }
void MatrixMultiplyTranslation(mat4_t m, vec_t x, vec_t y, vec_t z) { #if 1 mat4_t tmp, trans; mat4_copy(m, tmp); mat4_reset_translate(trans, x, y, z); mat4_mult(tmp, trans, m); #else m[12] += m[0] * x + m[4] * y + m[8] * z; m[13] += m[1] * x + m[5] * y + m[9] * z; m[14] += m[2] * x + m[6] * y + m[10] * z; m[15] += m[3] * x + m[7] * y + m[11] * z; #endif }
Torus* initTorus(const mat4 inv_transform, const float swept_radius, const float tube_radius, const float phi, Material* mat) { GenericTorus* gt = (GenericTorus*)malloc(sizeof(GenericTorus)); gt->swept_radius = swept_radius; gt->tube_radius = tube_radius; gt->phi = phi; gt->mat = mat; Torus* torus = (Torus*)malloc(sizeof(Torus)); torus->obj.ptr = gt; torus->obj.type = GENERICTORUS; torus->mat = mat; mat4_copy(torus->inv_transform, inv_transform); return torus; }
Box* initBox(const mat4 inv_transform, const float x_span, const float y_span, const float z_span, Material* mat) { float half_x = x_span / 2.0f; float half_y = y_span / 2.0f; float half_z = z_span / 2.0f; AABox* aabox = (AABox*)malloc(sizeof(AABox)); vec3_assign(aabox->min, -half_x, -half_y, -half_z); vec3_assign(aabox->max, half_x, half_y, half_z); aabox->mat = mat; Box* box = (Box*)malloc(sizeof(Box)); box->obj.ptr = aabox; box->obj.type = AABOX; box->mat = mat; mat4_copy(box->inv_transform, inv_transform); return box; }
void DebugEmitterComponent::_GetNodeTransform(ModelNode* node, mat4* result) { std::stack<mat4*> transform_stack; // Build the stack ModelNode* currentNode = node; while (currentNode) { transform_stack.push(¤tNode->Transformation); currentNode = currentNode->ParentNode; } mat4 res; _CalculateNodeTransform(transform_stack, &res); mat4_copy(*result, res); }
static bool ray_surface_intersect(Ray ray, const Surface *surf, Hit *hit) { float ts[2] = {-HUGE_VAL, -HUGE_VAL}, t; Vec3 tnormals[2] = {{0,0,0},{0,0,0}}, tnormal; Ray tray; Mat4 normal_matrix; Shape *shape = surf->shape; int hits; mat4_copy(normal_matrix, surf->world_to_model); mat4_transpose(normal_matrix); tray.origin = mat4_transform3_homo(surf->world_to_model, ray.origin); tray.direction = mat4_transform3_hetero(surf->world_to_model, ray.direction); tray.near = ray.near; tray.far = ray.far; switch(shape->type) { case SHAPE_PLANE: hits = ray_plane_intersect(tray, shape->u.plane, ts, tnormals); break; case SHAPE_DISK: hits = ray_disk_intersect(tray, shape->u.disk, ts, tnormals); break; case SHAPE_SPHERE: hits = ray_sphere_intersect(tray, shape->u.sphere, ts, tnormals); break; case SHAPE_CYLINDER: hits = ray_cylinder_intersect(tray, shape->u.cylinder, ts, tnormals); break; case SHAPE_CONE: hits = ray_cone_intersect(tray, shape->u.cone, ts, tnormals); break; case SHAPE_MESH: hits = ray_mesh_intersect(tray, shape->u.mesh, ts, tnormals); break; default: printf("Unknown shape\n"); return false; break; } /* We're looking for the smallest hit that is between the near and far * planes of the ray. */ if (hits == 0) return false; if (hits == 1) { if (ts[0] < ray.near || ts[0] > ray.far) return false; t = ts[0]; tnormal = tnormals[0]; } else if (hits == 2) { bool t0_ok = ts[0] >= ray.near && ts[0] <= ray.far; bool t1_ok = ts[1] >= ray.near && ts[1] <= ray.far; if (!t0_ok && !t1_ok) { return false; } else if (t0_ok && !t1_ok) { t = ts[0]; tnormal = tnormals[0]; } else if (!t0_ok && t1_ok) { t = ts[1]; tnormal = tnormals[1]; } else { if (ts[0] < ts[1]) { t = ts[0]; tnormal = tnormals[0]; } else { t = ts[1]; tnormal = tnormals[1]; } } } else { printf("General t finding code unimplemented\n"); return false; } hit->t = t; hit->position = vec3_add(ray.origin, vec3_scale(t, ray.direction)); hit->normal = vec3_normalize(mat4_transform3_hetero(normal_matrix, tnormal)); return true; }