Skip to content

Add "set_bone_position" API method #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions defold-spine/src/comp_spine_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1396,6 +1396,24 @@ namespace dmSpine
*instance_id = dmGameObject::GetIdentifier(bone_instance);
return true;
}

bool CompSpineModelSetBonePosition(SpineModelComponent* component, dmhash_t bone_name, Point3 position)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our code code convention here is const dmVMath::Point3& position)

{
SpineModelResource* spine_model = component->m_Resource;
SpineSceneResource* spine_scene = spine_model->m_SpineScene;
uint32_t* index = spine_scene->m_BoneNameToIndex.Get(bone_name);

if (!index)
return false;

spBone* bone = component->m_SkeletonInstance->bones[*index];
dmVMath::Vector3 model_pos = (dmVMath::Vector3)dmTransform::Apply(dmTransform::Inv(dmTransform::Mul(dmGameObject::GetWorldTransform(component->m_Instance), component->m_Transform)), position);

bone->x = model_pos.getX();
bone->y = model_pos.getY();

return true;
}
}

DM_DECLARE_COMPONENT_TYPE(ComponentTypeSpineModelExt, "spinemodelc", dmSpine::CompTypeSpineModelCreate, dmSpine::CompTypeSpineModelDestroy);
2 changes: 2 additions & 0 deletions defold-spine/src/comp_spine_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ namespace dmSpine

bool CompSpineModelGetBone(SpineModelComponent* component, dmhash_t bone_name, dmhash_t* instance_id);

bool CompSpineModelSetBonePosition(SpineModelComponent* component, dmhash_t bone_name, Vectormath::Aos::Point3 position);
Copy link
Contributor

@JCash JCash Feb 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The correct type is const dmVMath::Point3&


}

#endif // DM_GAMESYS_COMP_SPINE_MODEL_H
11 changes: 11 additions & 0 deletions defold-spine/src/res_spine_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ namespace dmSpine
}
}

{
uint32_t count = resource->m_Skeleton->bonesCount;
resource->m_BoneNameToIndex.SetCapacity(dmMath::Max(1U, count/3), count);
for (int n = 0; n < count; ++n)
{
dmhash_t name_hash = dmHashString64(resource->m_Skeleton->bones[n]->name);
resource->m_BoneNameToIndex.Put(name_hash, n);
DEBUGLOG("bone: %d %s", n, resource->m_Skeleton->bones[n]->name);
}
}

return dmResource::RESULT_OK;
}

Expand Down
1 change: 1 addition & 0 deletions defold-spine/src/res_spine_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace dmSpine
dmHashTable64<uint32_t> m_SkinNameToIndex;
dmHashTable64<uint32_t> m_SlotNameToIndex;
dmHashTable64<uint32_t> m_IKNameToIndex;
dmHashTable64<uint32_t> m_BoneNameToIndex;
dmHashTable64<const char*> m_AttachmentHashToName; // makes it easy for us to do a reverse hash for attachments
};
}
Expand Down
42 changes: 42 additions & 0 deletions defold-spine/src/script_spine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,47 @@ namespace dmSpine
return 0;
}

/*# Set world space bone position
* Note that bones positions will be overwritten by active animations and constraints(IK, Path, Transform...), only change positions of bones that is not affected by those.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct tag for notes is @note

*
* @name spine.get_go
* @param url [type:string|hash|url] the spine model to query
* @param bone_id [type:string|hash] id of the corresponding bone
* @param position [type:vector3] position in world space
* @examples
*
* The following examples assumes that the spine model has id "spinemodel" and it has bone named "crosshair"
*
* How to set bone position to mouse position("crosshair" could be IK target for example):
*
* ```lua
* function on_input(self)
* if action_id == nil then
* spine.set_bone_position("#spinemodel", "crosshair", vmath.vector3(action.x, action.y, 0))
* end
* end
* ```
*/
static int SpineComp_SetBonePosition(lua_State* L)
{
DM_LUA_STACK_CHECK(L, 0);

SpineModelComponent* component = 0;
dmMessage::URL receiver; // needed for error output
dmGameObject::GetComponentFromLua(L, 1, SPINE_MODEL_EXT, 0, (void**)&component, &receiver);

dmhash_t bone_id = dmScript::CheckHashOrString(L, 2);
Vectormath::Aos::Vector3* position = dmScript::CheckVector3(L, 3);
Comment on lines +711 to +712
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only do casts if we know it's the correct type.
Here, they're not the same: Vector3 != Point3

You can create a Point3 like so: Point3(v3)


if (!CompSpineModelSetBonePosition(component, bone_id, (Point3)*position))
{
char buffer[128];
return DM_LUA_ERROR("the bone '%s' could not be found in component %s", lua_tostring(L, 2), dmScript::UrlToString(&receiver, buffer, sizeof(buffer)));
}

return 0;
}

/** Deprecated: set a shader constant for a spine model
* Sets a shader constant for a spine model component.
* The constant must be defined in the material assigned to the spine model.
Expand Down Expand Up @@ -780,6 +821,7 @@ namespace dmSpine
{"set_ik_target_position", SpineComp_SetIKTargetPosition},
{"set_ik_target", SpineComp_SetIKTarget},
{"reset_ik_target", SpineComp_ResetIK},
{"set_bone_position", SpineComp_SetBonePosition},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In our api, we use "world" in the names (See go.get_world_position())
This function should be called set_world_bone_position().

That, or make it accept local space coordinate.

{"set_constant", SpineComp_SetConstant},
{"reset_constant", SpineComp_ResetConstant},
{0, 0}
Expand Down