Path: blob/master/tests/scene/test_convert_transform_modifier_3d.h
10277 views
/**************************************************************************/1/* test_convert_transform_modifier_3d.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "tests/test_macros.h"3334#include "scene/3d/bone_attachment_3d.h"35#include "scene/3d/convert_transform_modifier_3d.h"3637namespace TestConvertTransformModifier3D {3839Transform3D make_random_transform_3d(int p_seed) {40RandomNumberGenerator rng;41rng.set_seed(p_seed);4243Vector3 pos;44pos.x = rng.randf_range(-10.0, 10.0);45rng.set_seed(++p_seed);46pos.y = rng.randf_range(-10.0, 10.0);47rng.set_seed(++p_seed);48pos.z = rng.randf_range(-10.0, 10.0);49rng.set_seed(++p_seed);5051Quaternion rot;52rot.x = rng.randf_range(-1.0, 1.0);53rng.set_seed(++p_seed);54rot.y = rng.randf_range(-1.0, 1.0);55rng.set_seed(++p_seed);56rot.z = rng.randf_range(-1.0, 1.0);57rng.set_seed(++p_seed);58rot.w = rng.randf_range(-1.0, 1.0);59rng.set_seed(++p_seed);60rot = rot.normalized();6162Vector3 scl;63scl.x = rng.randf_range(0.5, 2.0);64rng.set_seed(++p_seed);65scl.y = rng.randf_range(0.5, 2.0);66rng.set_seed(++p_seed);67scl.z = rng.randf_range(0.5, 2.0);68rng.set_seed(++p_seed);6970return Transform3D(Basis(rot).scaled(scl), pos);71}7273TEST_CASE("[SceneTree][ConvertTransformModifier3D]") {74SceneTree *tree = SceneTree::get_singleton();75int seed = 12345;76Skeleton3D *skeleton = memnew(Skeleton3D);77ConvertTransformModifier3D *mod = memnew(ConvertTransformModifier3D);7879// Instead of awaiting the process to wait to finish deferred process and watch "skeleton_updated" signal,80// force notify NOTIFICATION_UPDATE_SKELETON and get the modified pose from the BoneAttachment's transform.81BoneAttachment3D *modified = memnew(BoneAttachment3D);8283tree->get_root()->add_child(skeleton);8485int root = skeleton->add_bone("root");86skeleton->set_bone_rest(root, make_random_transform_3d(++seed));87skeleton->set_bone_pose(root, make_random_transform_3d(++seed));8889int apl_root = skeleton->add_bone("apl_root");90skeleton->set_bone_parent(apl_root, root);91skeleton->set_bone_rest(apl_root, make_random_transform_3d(++seed));92skeleton->set_bone_pose(apl_root, make_random_transform_3d(++seed));9394int apl_bone = skeleton->add_bone("apl_bone");95skeleton->set_bone_parent(apl_bone, apl_root);96skeleton->set_bone_rest(apl_bone, make_random_transform_3d(++seed));97skeleton->set_bone_pose(apl_bone, make_random_transform_3d(++seed));9899int tgt_root = skeleton->add_bone("tgt_root");100skeleton->set_bone_parent(tgt_root, root);101skeleton->set_bone_rest(tgt_root, make_random_transform_3d(++seed));102skeleton->set_bone_pose(tgt_root, make_random_transform_3d(++seed));103104int tgt_bone = skeleton->add_bone("tgt_bone");105skeleton->set_bone_parent(tgt_bone, tgt_root);106skeleton->set_bone_rest(tgt_bone, make_random_transform_3d(++seed));107skeleton->set_bone_pose(tgt_bone, make_random_transform_3d(++seed));108109skeleton->add_child(mod);110skeleton->add_child(modified);111modified->set_rotation_edit_mode(Node3D::ROTATION_EDIT_MODE_QUATERNION);112modified->set_bone_idx(apl_bone);113114mod->set_setting_count(1);115mod->set_reference_bone(0, tgt_bone);116mod->set_apply_bone(0, apl_bone);117118mod->set_reference_axis(0, Vector3::AXIS_X);119mod->set_apply_axis(0, Vector3::AXIS_Y);120121// ===== [ConvertTransformModifier3D] Position x to y =====122mod->set_reference_transform_mode(0, ConvertTransformModifier3D::TRANSFORM_MODE_POSITION);123mod->set_reference_range_min(0, -100.0);124mod->set_reference_range_max(0, 100.0);125mod->set_apply_transform_mode(0, ConvertTransformModifier3D::TRANSFORM_MODE_POSITION);126mod->set_apply_range_min(0, -100.0);127mod->set_apply_range_max(0, 100.0);128129SUBCASE("[ConvertTransformModifier3D] Position x to y, additive=false, relative=false") {130mod->set_additive(0, false);131mod->set_relative(0, false);132skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);133CHECK(Math::is_equal_approx(134skeleton->get_bone_pose_position(tgt_bone).x,135(skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).origin.y));136}137138SUBCASE("[ConvertTransformModifier3D] Position x to y, additive=true, relative=false") {139mod->set_additive(0, true);140mod->set_relative(0, false);141skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);142CHECK(Math::is_equal_approx(143skeleton->get_bone_pose_position(tgt_bone).x,144((skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).origin - skeleton->get_bone_pose_position(apl_bone)).y));145}146147SUBCASE("[ConvertTransformModifier3D] Position x to y, additive=false, relative=true") {148mod->set_additive(0, false);149mod->set_relative(0, true);150skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);151CHECK(Math::is_equal_approx(152(skeleton->get_bone_pose_position(tgt_bone) - skeleton->get_bone_rest(tgt_bone).origin).x,153((skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).origin - skeleton->get_bone_rest(apl_bone).origin).y));154}155156SUBCASE("[ConvertTransformModifier3D] Position x to y, additive=true, relative=true") {157mod->set_additive(0, true);158mod->set_relative(0, true);159skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);160CHECK(Math::is_equal_approx(161(skeleton->get_bone_pose_position(tgt_bone) - skeleton->get_bone_rest(tgt_bone).origin).x,162((skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).origin - skeleton->get_bone_pose_position(apl_bone)).y));163}164165// ===== [ConvertTransformModifier3D] Rotation (roll) x to y =====166mod->set_reference_transform_mode(0, ConvertTransformModifier3D::TRANSFORM_MODE_ROTATION);167mod->set_reference_range_min(0, -180.0);168mod->set_reference_range_max(0, 180.0);169mod->set_apply_transform_mode(0, ConvertTransformModifier3D::TRANSFORM_MODE_ROTATION);170mod->set_apply_range_min(0, -180.0);171mod->set_apply_range_max(0, 180.0);172173SUBCASE("[ConvertTransformModifier3D] Rotation (roll) x to y, additive=false, relative=false") {174mod->set_additive(0, false);175mod->set_relative(0, false);176skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);177CHECK(Math::is_equal_approx(178BoneConstraint3D::get_roll_angle(skeleton->get_bone_pose_rotation(tgt_bone), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_X)),179BoneConstraint3D::get_roll_angle((skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_rotation_quaternion(), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_Y))));180}181182SUBCASE("[ConvertTransformModifier3D] Rotation (roll) x to y, additive=true, relative=false") {183mod->set_additive(0, true);184mod->set_relative(0, false);185skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);186CHECK(Math::is_equal_approx(187BoneConstraint3D::get_roll_angle(skeleton->get_bone_pose_rotation(tgt_bone), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_X)),188BoneConstraint3D::get_roll_angle(skeleton->get_bone_pose_rotation(apl_bone).inverse() * (skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_rotation_quaternion(), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_Y))));189}190191SUBCASE("[ConvertTransformModifier3D] Rotation (roll) x to y, additive=false, relative=true") {192mod->set_additive(0, false);193mod->set_relative(0, true);194skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);195CHECK(Math::is_equal_approx(196BoneConstraint3D::get_roll_angle(skeleton->get_bone_rest(tgt_bone).basis.get_rotation_quaternion().inverse() * skeleton->get_bone_pose_rotation(tgt_bone), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_X)),197BoneConstraint3D::get_roll_angle(skeleton->get_bone_rest(apl_bone).basis.get_rotation_quaternion().inverse() * (skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_rotation_quaternion(), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_Y))));198}199200SUBCASE("[ConvertTransformModifier3D] Rotation (roll) x to y, additive=true, relative=true") {201mod->set_additive(0, true);202mod->set_relative(0, true);203skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);204CHECK(Math::is_equal_approx(205BoneConstraint3D::get_roll_angle(skeleton->get_bone_rest(tgt_bone).basis.get_rotation_quaternion().inverse() * skeleton->get_bone_pose_rotation(tgt_bone), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_X)),206BoneConstraint3D::get_roll_angle(skeleton->get_bone_pose_rotation(apl_bone).inverse() * (skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_rotation_quaternion(), BoneConstraint3D::get_vector_from_axis(Vector3::AXIS_Y))));207}208209// ===== [ConvertTransformModifier3D] Scale x to y =====210mod->set_reference_transform_mode(0, ConvertTransformModifier3D::TRANSFORM_MODE_SCALE);211mod->set_reference_range_min(0, 0);212mod->set_reference_range_max(0, 10.0);213mod->set_apply_transform_mode(0, ConvertTransformModifier3D::TRANSFORM_MODE_SCALE);214mod->set_apply_range_min(0, 0);215mod->set_apply_range_max(0, 10.0);216217SUBCASE("[ConvertTransformModifier3D] Scale x to y, additive=false, relative=false") {218mod->set_additive(0, false);219mod->set_relative(0, false);220skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);221CHECK(Math::is_equal_approx(222skeleton->get_bone_pose_scale(tgt_bone).x,223(skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_scale().y));224}225226SUBCASE("[ConvertTransformModifier3D] Scale x to y, additive=true, relative=false") {227mod->set_additive(0, true);228mod->set_relative(0, false);229skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);230CHECK(Math::is_equal_approx(231skeleton->get_bone_pose_scale(tgt_bone).x,232((skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_scale() / skeleton->get_bone_pose_scale(apl_bone)).y));233}234235SUBCASE("[ConvertTransformModifier3D] Scale x to y, additive=false, relative=true") {236mod->set_additive(0, false);237mod->set_relative(0, true);238skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);239CHECK(Math::is_equal_approx(240(skeleton->get_bone_pose_scale(tgt_bone) / skeleton->get_bone_rest(tgt_bone).basis.get_scale()).x,241((skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_scale() / skeleton->get_bone_rest(apl_bone).basis.get_scale()).y));242}243244SUBCASE("[ConvertTransformModifier3D] Scale x to y, additive=true, relative=true") {245mod->set_additive(0, true);246mod->set_relative(0, true);247skeleton->notification(Skeleton3D::NOTIFICATION_UPDATE_SKELETON);248CHECK(Math::is_equal_approx(249(skeleton->get_bone_pose_scale(tgt_bone) / skeleton->get_bone_rest(tgt_bone).basis.get_scale()).x,250((skeleton->get_bone_global_pose(apl_root).affine_inverse() * modified->get_transform()).basis.get_scale() / skeleton->get_bone_pose_scale(apl_bone)).y));251}252253memdelete(modified);254memdelete(mod);255memdelete(skeleton);256}257} // namespace TestConvertTransformModifier3D258259260