Merge branch 'development' into ImGuiNoEntityProblem

Signed-off-by: John Jones-Steele <jjjoness@amazon.com>
monroegm-disable-blank-issue-2
John Jones-Steele 4 years ago
commit f24ce2a5bb

@ -42001,245 +42001,255 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<source>WORLD_RAYCASTMULTIPLELOCALSPACE_OUTPUT0_NAME</source>
<translation type="unfinished">Hits</translation>
</message>
<message id="WORLD_OVERLAPSPHERE_NAME">
<source>WORLD_OVERLAPSPHERE_NAME</source>
<message id="WORLD_OVERLAPSPHEREWITHGROUP_NAME">
<source>WORLD_OVERLAPSPHEREWITHGROUP_NAME</source>
<translation type="unfinished">Overlap Sphere</translation>
</message>
<message id="WORLD_OVERLAPSPHERE_PARAM0_NAME">
<source>WORLD_OVERLAPSPHERE_PARAM0_NAME</source>
<message id="WORLD_OVERLAPSPHEREWITHGROUP_PARAM0_NAME">
<source>WORLD_OVERLAPSPHEREWITHGROUP_PARAM0_NAME</source>
<translation type="unfinished">Position</translation>
</message>
<message id="WORLD_OVERLAPSPHERE_PARAM1_NAME">
<source>WORLD_OVERLAPSPHERE_PARAM1_NAME</source>
<message id="WORLD_OVERLAPSPHEREWITHGROUP_PARAM1_NAME">
<source>WORLD_OVERLAPSPHEREWITHGROUP_PARAM1_NAME</source>
<translation type="unfinished">Radius</translation>
</message>
<message id="WORLD_OVERLAPSPHERE_PARAM2_NAME">
<source>WORLD_OVERLAPSPHERE_PARAM2_NAME</source>
<message id="WORLD_OVERLAPSPHEREWITHGROUP_PARAM2_NAME">
<source>WORLD_OVERLAPSPHEREWITHGROUP_PARAM2_NAME</source>
<translation type="unfinished">Collision Group</translation>
</message>
<message id="WORLD_OVERLAPSPHERE_PARAM3_NAME">
<source>WORLD_OVERLAPSPHERE_PARAM3_NAME</source>
<message id="WORLD_OVERLAPSPHEREWITHGROUP_PARAM3_NAME">
<source>WORLD_OVERLAPSPHEREWITHGROUP_PARAM3_NAME</source>
<translation type="unfinished">Ignore</translation>
</message>
<message id="WORLD_OVERLAPSPHERE_OUTPUT0_NAME">
<source>WORLD_OVERLAPSPHERE_OUTPUT0_NAME</source>
<message id="WORLD_OVERLAPSPHEREWITHGROUP_OUTPUT0_NAME">
<source>WORLD_OVERLAPSPHEREWITHGROUP_OUTPUT0_NAME</source>
<translation type="unfinished">Is Overlapping</translation>
</message>
<message id="WORLD_OVERLAPSPHERE_OUTPUT1_NAME">
<source>WORLD_OVERLAPSPHERE_OUTPUT1_NAME</source>
<message id="WORLD_OVERLAPSPHEREWITHGROUP_OUTPUT1_NAME">
<source>WORLD_OVERLAPSPHEREWITHGROUP_OUTPUT1_NAME</source>
<translation type="unfinished">Overlaps</translation>
</message>
<message id="WORLD_OVERLAPBOX_NAME">
<source>WORLD_OVERLAPBOX_NAME</source>
<message id="WORLD_OVERLAPBOXWITHGROUP_NAME">
<source>WORLD_OVERLAPBOXWITHGROUP_NAME</source>
<translation type="unfinished">Overlap Box</translation>
</message>
<message id="WORLD_OVERLAPBOX_PARAM0_NAME">
<source>WORLD_OVERLAPBOX_PARAM0_NAME</source>
<message id="WORLD_OVERLAPBOXWITHGROUP_PARAM0_NAME">
<source>WORLD_OVERLAPBOXWITHGROUP_PARAM0_NAME</source>
<translation type="unfinished">Pose</translation>
</message>
<message id="WORLD_OVERLAPBOX_PARAM1_NAME">
<source>WORLD_OVERLAPBOX_PARAM1_NAME</source>
<message id="WORLD_OVERLAPBOXWITHGROUP_PARAM1_NAME">
<source>WORLD_OVERLAPBOXWITHGROUP_PARAM1_NAME</source>
<translation type="unfinished">Dimensions</translation>
</message>
<message id="WORLD_OVERLAPBOX_PARAM2_NAME">
<source>WORLD_OVERLAPBOX_PARAM2_NAME</source>
<message id="WORLD_OVERLAPBOXWITHGROUP_PARAM2_NAME">
<source>WORLD_OVERLAPBOXWITHGROUP_PARAM2_NAME</source>
<translation type="unfinished">Collision Group</translation>
</message>
<message id="WORLD_OVERLAPBOX_PARAM3_NAME">
<source>WORLD_OVERLAPBOX_PARAM3_NAME</source>
<message id="WORLD_OVERLAPBOXWITHGROUP_PARAM3_NAME">
<source>WORLD_OVERLAPBOXWITHGROUP_PARAM3_NAME</source>
<translation type="unfinished">Ignore</translation>
</message>
<message id="WORLD_OVERLAPBOX_OUTPUT0_NAME">
<source>WORLD_OVERLAPBOX_OUTPUT0_NAME</source>
<message id="WORLD_OVERLAPBOXWITHGROUP_OUTPUT0_NAME">
<source>WORLD_OVERLAPBOXWITHGROUP_OUTPUT0_NAME</source>
<translation type="unfinished">Is Overlapping</translation>
</message>
<message id="WORLD_OVERLAPBOX_OUTPUT1_NAME">
<source>WORLD_OVERLAPBOX_OUTPUT1_NAME</source>
<message id="WORLD_OVERLAPBOXWITHGROUP_OUTPUT1_NAME">
<source>WORLD_OVERLAPBOXWITHGROUP_OUTPUT1_NAME</source>
<translation type="unfinished">Overlaps</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_NAME">
<source>WORLD_OVERLAPCAPSULE_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_NAME</source>
<translation type="unfinished">Overlap Capsule</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_PARAM0_NAME">
<source>WORLD_OVERLAPCAPSULE_PARAM0_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_PARAM0_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_PARAM0_NAME</source>
<translation type="unfinished">Pose</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_PARAM1_NAME">
<source>WORLD_OVERLAPCAPSULE_PARAM1_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_PARAM1_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_PARAM1_NAME</source>
<translation type="unfinished">Height</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_PARAM2_NAME">
<source>WORLD_OVERLAPCAPSULE_PARAM2_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_PARAM2_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_PARAM2_NAME</source>
<translation type="unfinished">Radius</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_PARAM3_NAME">
<source>WORLD_OVERLAPCAPSULE_PARAM3_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_PARAM3_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_PARAM3_NAME</source>
<translation type="unfinished">Collision Group</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_PARAM4_NAME">
<source>WORLD_OVERLAPCAPSULE_PARAM4_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_PARAM4_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_PARAM4_NAME</source>
<translation type="unfinished">Ignore</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_OUTPUT0_NAME">
<source>WORLD_OVERLAPCAPSULE_OUTPUT0_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_OUTPUT0_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_OUTPUT0_NAME</source>
<translation type="unfinished">Is Overlapping</translation>
</message>
<message id="WORLD_OVERLAPCAPSULE_OUTPUT1_NAME">
<source>WORLD_OVERLAPCAPSULE_OUTPUT1_NAME</source>
<message id="WORLD_OVERLAPCAPSULEWITHGROUP_OUTPUT1_NAME">
<source>WORLD_OVERLAPCAPSULEWITHGROUP_OUTPUT1_NAME</source>
<translation type="unfinished">Overlaps</translation>
</message>
<message id="WORLD_SPHERECAST_NAME">
<source>WORLD_SPHERECAST_NAME</source>
</message>
<message id="WORLD_SPHERECASTWITHGROUP_NAME">
<source>WORLD_SPHERECASTWITHGROUP_NAME</source>
<translation type="unfinished">Sphere Cast</translation>
</message>
<message id="WORLD_SPHERECAST_PARAM0_NAME">
<source>WORLD_SPHERECAST_PARAM0_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_PARAM0_NAME">
<source>WORLD_SPHERECASTWITHGROUP_PARAM0_NAME</source>
<translation type="unfinished">Distance</translation>
</message>
<message id="WORLD_SPHERECAST_PARAM1_NAME">
<source>WORLD_SPHERECAST_PARAM1_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_PARAM1_NAME">
<source>WORLD_SPHERECASTWITHGROUP_PARAM1_NAME</source>
<translation type="unfinished">Start Pose</translation>
</message>
<message id="WORLD_SPHERECAST_PARAM2_NAME">
<source>WORLD_SPHERECAST_PARAM2_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_PARAM2_NAME">
<source>WORLD_SPHERECASTWITHGROUP_PARAM2_NAME</source>
<translation type="unfinished">Direction</translation>
</message>
<message id="WORLD_SPHERECAST_PARAM3_NAME">
<source>WORLD_SPHERECAST_PARAM3_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_PARAM3_NAME">
<source>WORLD_SPHERECASTWITHGROUP_PARAM3_NAME</source>
<translation type="unfinished">Radius</translation>
</message>
<message id="WORLD_SPHERECAST_PARAM4_NAME">
<source>WORLD_SPHERECAST_PARAM4_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_PARAM4_NAME">
<source>WORLD_SPHERECASTWITHGROUP_PARAM4_NAME</source>
<translation type="unfinished">Collision Group</translation>
</message>
<message id="WORLD_SPHERECAST_PARAM5_NAME">
<source>WORLD_SPHERECAST_PARAM5_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_PARAM5_NAME">
<source>WORLD_SPHERECASTWITHGROUP_PARAM5_NAME</source>
<translation type="unfinished">Ignore</translation>
</message>
<message id="WORLD_SPHERECAST_OUTPUT0_NAME">
<source>WORLD_SPHERECAST_OUTPUT0_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_OUTPUT0_NAME">
<source>WORLD_SPHERECASTWITHGROUP_OUTPUT0_NAME</source>
<translation type="unfinished">Object Hit</translation>
</message>
<message id="WORLD_SPHERECAST_OUTPUT1_NAME">
<source>WORLD_SPHERECAST_OUTPUT1_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_OUTPUT1_NAME">
<source>WORLD_SPHERECASTWITHGROUP_OUTPUT1_NAME</source>
<translation type="unfinished">Position</translation>
</message>
<message id="WORLD_SPHERECAST_OUTPUT2_NAME">
<source>WORLD_SPHERECAST_OUTPUT2_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_OUTPUT2_NAME">
<source>WORLD_SPHERECASTWITHGROUP_OUTPUT2_NAME</source>
<translation type="unfinished">Normal</translation>
</message>
<message id="WORLD_SPHERECAST_OUTPUT3_NAME">
<source>WORLD_SPHERECAST_OUTPUT3_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_OUTPUT3_NAME">
<source>WORLD_SPHERECASTWITHGROUP_OUTPUT3_NAME</source>
<translation type="unfinished">Distance</translation>
</message>
<message id="WORLD_SPHERECAST_OUTPUT4_NAME">
<source>WORLD_SPHERECAST_OUTPUT4_NAME</source>
<message id="WORLD_SPHERECASTWITHGROUP_OUTPUT4_NAME">
<source>WORLD_SPHERECASTWITHGROUP_OUTPUT4_NAME</source>
<translation type="unfinished">EntityId</translation>
</message>
<message id="WORLD_BOXCAST_NAME">
<source>WORLD_BOXCAST_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_NAME">
<source>WORLD_BOXCASTWITHGROUP_NAME</source>
<translation type="unfinished">Box Cast</translation>
</message>
<message id="WORLD_BOXCAST_PARAM0_NAME">
<source>WORLD_BOXCAST_PARAM0_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_PARAM0_NAME">
<source>WORLD_BOXCASTWITHGROUP_PARAM0_NAME</source>
<translation type="unfinished">Distance</translation>
</message>
<message id="WORLD_BOXCAST_PARAM1_NAME">
<source>WORLD_BOXCAST_PARAM1_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_PARAM1_NAME">
<source>WORLD_BOXCASTWITHGROUP_PARAM1_NAME</source>
<translation type="unfinished">Start Pose</translation>
</message>
<message id="WORLD_BOXCAST_PARAM2_NAME">
<source>WORLD_BOXCAST_PARAM2_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_PARAM2_NAME">
<source>WORLD_BOXCASTWITHGROUP_PARAM2_NAME</source>
<translation type="unfinished">Direction</translation>
</message>
<message id="WORLD_BOXCAST_PARAM3_NAME">
<source>WORLD_BOXCAST_PARAM3_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_PARAM3_NAME">
<source>WORLD_BOXCASTWITHGROUP_PARAM3_NAME</source>
<translation type="unfinished">Dimensions</translation>
</message>
<message id="WORLD_BOXCAST_PARAM4_NAME">
<source>WORLD_BOXCAST_PARAM4_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_PARAM4_NAME">
<source>WORLD_BOXCASTWITHGROUP_PARAM4_NAME</source>
<translation type="unfinished">Collision Group</translation>
</message>
<message id="WORLD_BOXCAST_PARAM5_NAME">
<source>WORLD_BOXCAST_PARAM5_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_PARAM5_NAME">
<source>WORLD_BOXCASTWITHGROUP_PARAM5_NAME</source>
<translation type="unfinished">Ignore</translation>
</message>
<message id="WORLD_BOXCAST_OUTPUT0_NAME">
<source>WORLD_BOXCAST_OUTPUT0_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_OUTPUT0_NAME">
<source>WORLD_BOXCASTWITHGROUP_OUTPUT0_NAME</source>
<translation type="unfinished">Object Hit</translation>
</message>
<message id="WORLD_BOXCAST_OUTPUT1_NAME">
<source>WORLD_BOXCAST_OUTPUT1_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_OUTPUT1_NAME">
<source>WORLD_BOXCASTWITHGROUP_OUTPUT1_NAME</source>
<translation type="unfinished">Position</translation>
</message>
<message id="WORLD_BOXCAST_OUTPUT2_NAME">
<source>WORLD_BOXCAST_OUTPUT2_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_OUTPUT2_NAME">
<source>WORLD_BOXCASTWITHGROUP_OUTPUT2_NAME</source>
<translation type="unfinished">Normal</translation>
</message>
<message id="WORLD_BOXCAST_OUTPUT3_NAME">
<source>WORLD_BOXCAST_OUTPUT3_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_OUTPUT3_NAME">
<source>WORLD_BOXCASTWITHGROUP_OUTPUT3_NAME</source>
<translation type="unfinished">Distance</translation>
</message>
<message id="WORLD_BOXCAST_OUTPUT4_NAME">
<source>WORLD_BOXCAST_OUTPUT4_NAME</source>
<message id="WORLD_BOXCASTWITHGROUP_OUTPUT4_NAME">
<source>WORLD_BOXCASTWITHGROUP_OUTPUT4_NAME</source>
<translation type="unfinished">EntityId</translation>
</message>
<message id="WORLD_CAPSULECAST_NAME">
<source>WORLD_CAPSULECAST_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_NAME</source>
<translation type="unfinished">Capsule Cast</translation>
</message>
<message id="WORLD_CAPSULECAST_PARAM0_NAME">
<source>WORLD_CAPSULECAST_PARAM0_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_PARAM0_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_PARAM0_NAME</source>
<translation type="unfinished">Distance</translation>
</message>
<message id="WORLD_CAPSULECAST_PARAM1_NAME">
<source>WORLD_CAPSULECAST_PARAM1_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_PARAM1_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_PARAM1_NAME</source>
<translation type="unfinished">Start Pose</translation>
</message>
<message id="WORLD_CAPSULECAST_PARAM2_NAME">
<source>WORLD_CAPSULECAST_PARAM2_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_PARAM2_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_PARAM2_NAME</source>
<translation type="unfinished">Direction</translation>
</message>
<message id="WORLD_CAPSULECAST_PARAM3_NAME">
<source>WORLD_CAPSULECAST_PARAM3_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_PARAM3_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_PARAM3_NAME</source>
<translation type="unfinished">Height</translation>
</message>
<message id="WORLD_CAPSULECAST_PARAM4_NAME">
<source>WORLD_CAPSULECAST_PARAM4_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_PARAM4_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_PARAM4_NAME</source>
<translation type="unfinished">Radius</translation>
</message>
<message id="WORLD_CAPSULECAST_PARAM5_NAME">
<source>WORLD_CAPSULECAST_PARAM5_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_PARAM5_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_PARAM5_NAME</source>
<translation type="unfinished">Collision Group</translation>
</message>
<message id="WORLD_CAPSULECAST_PARAM6_NAME">
<source>WORLD_CAPSULECAST_PARAM6_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_PARAM6_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_PARAM6_NAME</source>
<translation type="unfinished">Ignore</translation>
</message>
<message id="WORLD_CAPSULECAST_OUTPUT0_NAME">
<source>WORLD_CAPSULECAST_OUTPUT0_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_OUTPUT0_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_OUTPUT0_NAME</source>
<translation type="unfinished">Object Hit</translation>
</message>
<message id="WORLD_CAPSULECAST_OUTPUT1_NAME">
<source>WORLD_CAPSULECAST_OUTPUT1_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_OUTPUT1_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_OUTPUT1_NAME</source>
<source>WORLD_CAPSULECASTWITHGROUP_OUTPUT1_NAME</source>
<translation type="unfinished">Position</translation>
</message>
<message id="WORLD_BOXCAST_OUTPUT2_NAME">
<source>WORLD_BOXCAST_OUTPUT2_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_OUTPUT2_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_OUTPUT2_NAME</source>
<translation type="unfinished">Normal</translation>
</message>
<message id="WORLD_CAPSULECAST_OUTPUT3_NAME">
<source>WORLD_CAPSULECAST_OUTPUT3_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_OUTPUT3_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_OUTPUT3_NAME</source>
<translation type="unfinished">Distance</translation>
</message>
<message id="WORLD_CAPSULECAST_OUTPUT4_NAME">
<source>WORLD_CAPSULECAST_OUTPUT4_NAME</source>
<message id="WORLD_CAPSULECASTWITHGROUP_OUTPUT4_NAME">
<source>WORLD_CAPSULECASTWITHGROUP_OUTPUT4_NAME</source>
<translation type="unfinished">EntityId</translation>
</message>
<message id="WORLD_RAYCASTLOCALSPACEWITHGROUP_NAME">
<source>WORLD_RAYCASTLOCALSPACEWITHGROUP_NAME</source>
<translation type="unfinished">Raycast (Local Space)</translation>
</message>
<message id="WORLD_RAYCASTMULTIPLELOCALSPACEWITHGROUP_NAME">
<source>WORLD_RAYCASTMULTIPLELOCALSPACEWITHGROUP_NAME</source>
<translation type="unfinished">Raycast Multiple (Local Space)</translation>
</message>
<message id="WORLD_RAYCASTWORLDSPACEWITHGROUP_NAME">
<source>WORLD_RAYCASTWORLDSPACEWITHGROUP_NAME</source>
<translation type="unfinished">Raycast (World Space)</translation>
</message>
</context>
<context>
<name>EBus: CollisionFilteringBus</name>
@ -42368,7 +42378,7 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<name>EBus: RigidBodyRequestBus</name>
<message id="RIGIDBODYREQUESTBUS_NAME">
<source>RIGIDBODYREQUESTBUS_NAME</source>
<translation type="unfinished">RigidBody</translation>
<translation type="unfinished">Rigid Body</translation>
</message>
<message id="RIGIDBODYREQUESTBUS_TOOLTIP">
<source>RIGIDBODYREQUESTBUS_TOOLTIP</source>
@ -42413,6 +42423,23 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<source>RIGIDBODYREQUESTBUS_ISPHYSICSENABLED_OUTPUT0_TOOLTIP</source>
<translation type="unfinished">Indicates whether physics is enabled</translation>
</message>
<message id="RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_NAME">
<source>RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_NAME</source>
<comment>Class/Bus: RigidBodyRequestBus Event/Method: IsGravityEnabled</comment>
<translation type="unfinished">Is Gravity Enabled</translation>
</message>
<message id="RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_TOOLTIP">
<source>RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_TOOLTIP</source>
<translation type="unfinished">Returns true if the rigid body has gravity enabled</translation>
</message>
<message id="RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_OUTPUT0_NAME">
<source>RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_OUTPUT0_NAME</source>
<translation type="unfinished">Enabled</translation>
</message>
<message id="RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_OUTPUT0_TOOLTIP">
<source>RIGIDBODYREQUESTBUS_ISGRAVITYENABLED_OUTPUT0_TOOLTIP</source>
<translation type="unfinished">Indicates whether gravity is enabled</translation>
</message>
<message id="RIGIDBODYREQUESTBUS_GETCENTEROFMASSWORLD_NAME">
<source>RIGIDBODYREQUESTBUS_GETCENTEROFMASSWORLD_NAME</source>
<comment>Class/Bus: RigidBodyRequestBus Event/Method: GetCenterOfMassWorld</comment>
@ -42915,7 +42942,50 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<source>RIGIDBODYREQUESTBUS_GETAABB_OUTPUT0_TOOLTIP</source>
<translation type="unfinished">The aabb of the rigid body</translation>
</message>
</context>
</context>
<context>
<name>Method: SceneQueries</name>
<message id="SCENEQUERIES_NAME">
<source>SCENEQUERIES_NAME</source>
<translation type="unfinished">Scene Queries</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_NAME">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_NAME</source>
<translation type="unfinished">Create Raycast Request</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM0_NAME">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM0_NAME</source>
<translation type="unfinished">Start</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM0_TOOLTIP">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM0_TOOLTIP</source>
<translation type="unfinished">The position from which the raycast starts</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM1_NAME">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM1_NAME</source>
<translation type="unfinished">Direction</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM1_TOOLTIP">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM1_TOOLTIP</source>
<translation type="unfinished">The (normalized) direction in which to fire the raycast</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM2_NAME">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM2_NAME</source>
<translation type="unfinished">Distance</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM2_TOOLTIP">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM2_TOOLTIP</source>
<translation type="unfinished">The length of the raycast</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM3_NAME">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM3_NAME</source>
<translation type="unfinished">Collision Group</translation>
</message>
<message id="SCENEQUERIES_CREATERAYCASTREQUEST_PARAM3_TOOLTIP">
<source>SCENEQUERIES_CREATERAYCASTREQUEST_PARAM3_TOOLTIP</source>
<translation type="unfinished">Allows filtering of objects intersecting the raycast based on their collision layers</translation>
</message>
</context>
<context>
<name>Handler: TriggerNotificationBus</name>
<message id="HANDLER_TRIGGERNOTIFICATIONBUS_NAME">
@ -43199,12 +43269,12 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<source>PHYSXCHARACTERCONTROLLERREQUESTBUS_NAME</source>
<translation type="unfinished">Character Controller (PhysX Specific)</translation>
</message>
<message id="CHARACTERCONTROLLERREQUESTBUS_TOOLTIP">
<source>CHARACTERCONTROLLERREQUESTBUS_TOOLTIP</source>
<message id="PHYSXCHARACTERCONTROLLERREQUESTBUS_TOOLTIP">
<source>PHYSXCHARACTERCONTROLLERREQUESTBUS_TOOLTIP</source>
<translation type="unfinished">PhysX Character Controller Request Bus</translation>
</message>
<message id="CHARACTERCONTROLLERREQUESTBUS_CATEGORY">
<source>CHARACTERCONTROLLERREQUESTBUS_CATEGORY</source>
<message id="PHYSXCHARACTERCONTROLLERREQUESTBUS_CATEGORY">
<source>PHYSXCHARACTERCONTROLLERREQUESTBUS_CATEGORY</source>
<translation type="unfinished">PhysX</translation>
</message>
<message id="PHYSXCHARACTERCONTROLLERREQUESTBUS_GETHALFFORWARDEXTENT_NAME">
@ -44616,6 +44686,96 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<translation></translation>
</message>
</context>
<context>
<name>EBus: SimulatedBodyComponentRequestBus</name>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_NAME">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_NAME</source>
<translation type="unfinished">Simulated Body</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_TOOLTIP">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_TOOLTIP</source>
<translation type="unfinished">Simulated Body Component Request Bus</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_CATEGORY">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_CATEGORY</source>
<translation type="unfinished">PhysX</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_DISABLEPHYSICS_NAME">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_DISABLEPHYSICS_NAME</source>
<translation type="unfinished">Disable Physics</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_ENABLEPHYSICS_NAME">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_ENABLEPHYSICS_NAME</source>
<translation type="unfinished">Enable Physics</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_GETAABB_NAME">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_GETAABB_NAME</source>
<translation type="unfinished">Get AABB</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_ISPHYSICSENABLED_NAME">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_ISPHYSICSENABLED_NAME</source>
<translation type="unfinished">Is Physics Enabled</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_RAYCAST_NAME">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_RAYCAST_NAME</source>
<translation type="unfinished">Raycast (Single Body)</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_RAYCAST_TOOLTIP">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_RAYCAST_TOOLTIP</source>
<translation type="unfinished">Perform a raycast against a single simulated body (not the whole scene)</translation>
</message>
<message id="SIMULATEDBODYCOMPONENTREQUESTBUS_RAYCAST_PARAM0_NAME">
<source>SIMULATEDBODYCOMPONENTREQUESTBUS_RAYCAST_PARAM0_NAME</source>
<translation type="unfinished">Raycast Request</translation>
</message>
</context>
<context>
<name>EBus: WindRequestsBus</name>
<message id="WINDREQUESTSBUS_NAME">
<source>WINDREQUESTSBUS_NAME</source>
<translation type="unfinished">Wind</translation>
</message>
<message id="WINDREQUESTSBUS_TOOLTIP">
<source>WINDREQUESTSBUS_TOOLTIP</source>
<translation type="unfinished">Wind Request Bus</translation>
</message>
<message id="WINDREQUESTSBUS_CATEGORY">
<source>WINDREQUESTSBUS_CATEGORY</source>
<translation type="unfinished">PhysX</translation>
</message>
<message id="WINDREQUESTSBUS_GETGLOBALWIND_NAME">
<source>WINDREQUESTSBUS_GETGLOBALWIND_NAME</source>
<translation type="unfinished">Get Global Wind</translation>
</message>
<message id="WINDREQUESTSBUS_GETGLOBALWIND_OUTPUT0_NAME">
<source>WINDREQUESTSBUS_GETGLOBALWIND_OUTPUT0_NAME</source>
<translation type="unfinished">Wind Vector</translation>
</message>
<message id="WINDREQUESTSBUS_GETWINDATPOSITION_NAME">
<source>WINDREQUESTSBUS_GETWINDATPOSITION_NAME</source>
<translation type="unfinished">Get Wind At Position</translation>
</message>
<message id="WINDREQUESTSBUS_GETWINDATPOSITION_PARAM0_NAME">
<source>WINDREQUESTSBUS_GETWINDATPOSITION_PARAM0_NAME</source>
<translation type="unfinished">Position</translation>
</message>
<message id="WINDREQUESTSBUS_GETWINDATPOSITION_OUTPUT0_NAME">
<source>WINDREQUESTSBUS_GETWINDATPOSITION_OUTPUT0_NAME</source>
<translation type="unfinished">Wind Vector</translation>
</message>
<message id="WINDREQUESTSBUS_GETWINDINSIDEAABB_NAME">
<source>WINDREQUESTSBUS_GETWINDINSIDEAABB_NAME</source>
<translation type="unfinished">Get Wind Inside AABB</translation>
</message>
<message id="WINDREQUESTSBUS_GETWINDINSIDEAABB_PARAM0_NAME">
<source>WINDREQUESTSBUS_GETWINDINSIDEAABB_PARAM0_NAME</source>
<translation type="unfinished">AABB</translation>
</message>
<message id="WINDREQUESTSBUS_GETWINDINSIDEAABB_OUTPUT0_NAME">
<source>WINDREQUESTSBUS_GETWINDINSIDEAABB_OUTPUT0_NAME</source>
<translation type="unfinished">Wind Vector</translation>
</message>
</context>
<context>
<name>EBus: ChatPlayRequestBus</name>
<message id="CHATPLAYREQUESTBUS_NAME">
@ -62374,6 +62534,37 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
<translation></translation>
</message>
</context>
<context>
<name>EBus: NonUniformScaleRequestBus</name>
<message id="NONUNIFORMSCALEREQUESTBUS_NAME">
<source>NONUNIFORMSCALEREQUESTBUS_NAME</source>
<translation type="unfinished">Non-uniform Scale</translation>
</message>
<message id="NONUNIFORMSCALEREQUESTBUS_TOOLTIP">
<source>NONUNIFORMSCALEREQUESTBUS_TOOLTIP</source>
<translation type="unfinished">Non-uniform Scale Request Bus</translation>
</message>
<message id="NONUNIFORMSCALEREQUESTBUS_CATEGORY">
<source>NONUNIFORMSCALEREQUESTBUS_CATEGORY</source>
<translation type="unfinished">Entity</translation>
</message>
<message id="NONUNIFORMSCALEREQUESTBUS_GETSCALE_NAME">
<source>NONUNIFORMSCALEREQUESTBUS_GETSCALE_NAME</source>
<translation type="unfinished">Get Scale</translation>
</message>
<message id="NONUNIFORMSCALEREQUESTBUS_GETSCALE_OUTPUT0_NAME">
<source>NONUNIFORMSCALEREQUESTBUS_GETSCALE_OUTPUT0_NAME</source>
<translation type="unfinished">Non-uniform Scale</translation>
</message>
<message id="NONUNIFORMSCALEREQUESTBUS_SETSCALE_NAME">
<source>NONUNIFORMSCALEREQUESTBUS_SETSCALE_NAME</source>
<translation type="unfinished">Set Scale</translation>
</message>
<message id="NONUNIFORMSCALEREQUESTBUS_SETSCALE_PARAM0_NAME">
<source>NONUNIFORMSCALEREQUESTBUS_SETSCALE_PARAM0_NAME</source>
<translation type="unfinished">Non-uniform Scale</translation>
</message>
</context>
<context>
<name>EBus: TransformBus</name>
<message id="TRANSFORMBUS_NAME">

@ -67,6 +67,17 @@ namespace AzPhysics
}
}
// class for exposing free functions to script
class SceneQueries
{
public:
AZ_TYPE_INFO(SceneQueries, "{4EFA3DA5-C0E3-4753-8C55-202228CA527E}");
AZ_CLASS_ALLOCATOR(SceneQueries, AZ::SystemAllocator, 0);
SceneQueries() = default;
~SceneQueries() = default;
};
/*static*/ void SceneQueryRequest::Reflect(AZ::ReflectContext* context)
{
if (auto* serializeContext = azdynamic_cast<AZ::SerializeContext*>(context))
@ -96,6 +107,7 @@ namespace AzPhysics
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Property("Collision", BehaviorValueProperty(&SceneQueryRequest::m_collisionGroup))
// Until enum class support for behavior context is done, expose this as an int
->Property("QueryType", [](const SceneQueryRequest& self) { return static_cast<int>(self.m_queryType); },
@ -134,11 +146,28 @@ namespace AzPhysics
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Property("Distance", BehaviorValueProperty(&RayCastRequest::m_distance))
->Property("Start", BehaviorValueProperty(&RayCastRequest::m_start))
->Property("Direction", BehaviorValueProperty(&RayCastRequest::m_direction))
->Property("ReportMultipleHits", BehaviorValueProperty(&RayCastRequest::m_reportMultipleHits))
;
behaviorContext->Class<SceneQueries>("SceneQueries")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Method(
"CreateRayCastRequest",
[](const AZ::Vector3& start, const AZ::Vector3& direction, float distance, const AZStd::string& collisionGroup)
{
RayCastRequest request;
request.m_start = start;
request.m_direction = direction;
request.m_distance = distance;
request.m_collisionGroup = CollisionGroup(collisionGroup);
return request;
});
}
}
@ -162,6 +191,7 @@ namespace AzPhysics
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Property("Distance", BehaviorValueProperty(&ShapeCastRequest::m_distance))
->Property("Start", BehaviorValueProperty(&ShapeCastRequest::m_start))
->Property("Direction", BehaviorValueProperty(&ShapeCastRequest::m_direction))
@ -175,7 +205,6 @@ namespace AzPhysics
return ShapeCastRequestHelpers::CreateSphereCastRequest(
radius, startPose, direction, distance, queryType, collisionGroup, nullptr);
});
behaviorContext->Method(
"CreateBoxCastRequest",
[](const AZ::Vector3& boxDimensions, const AZ::Transform& startPose, const AZ::Vector3& direction, float distance,
@ -184,7 +213,6 @@ namespace AzPhysics
return ShapeCastRequestHelpers::CreateBoxCastRequest(
boxDimensions, startPose, direction, distance, queryType, collisionGroup, nullptr);
});
behaviorContext->Method(
"CreateCapsuleCastRequest",
[](float capsuleRadius, float capsuleHeight, const AZ::Transform& startPose, const AZ::Vector3& direction, float distance,
@ -267,6 +295,7 @@ namespace AzPhysics
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Property("Pose", BehaviorValueProperty(&OverlapRequest::m_pose))
;
@ -349,6 +378,7 @@ namespace AzPhysics
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "physics")
->Attribute(AZ::Script::Attributes::Category, "PhysX")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Property("Distance", BehaviorValueProperty(&SceneQueryHit::m_distance))
->Property("Position", BehaviorValueProperty(&SceneQueryHit::m_position))
->Property("Normal", BehaviorValueProperty(&SceneQueryHit::m_normal))

@ -51,7 +51,10 @@ namespace AzPhysics
->Method("GetOnPostsimulateEvent", getOnPostsimulateEvent)
->Attribute(AZ::Script::Attributes::AzEventDescription, postsimulateEventDescription)
->Method("GetSceneHandle", &SystemInterface::GetSceneHandle)
->Method("GetScene", &SystemInterface::GetScene);
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Method("GetScene", &SystemInterface::GetScene)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
;
behaviorContext->Method(
"GetPhysicsSystem",

@ -363,16 +363,16 @@ namespace AzToolsFramework::ViewportUi::Internal
{
// no background for the widget else each set of buttons/textfields/etc would have a black box around them
SetTransparentBackground(widget);
widget->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
widget->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
}
void ViewportUiDisplay::InitializeUiOverlay()
{
m_uiMainWindow.setObjectName(m_uiMainWindow.windowTitle());
m_uiMainWindow.setObjectName(QString("ViewportUiWindow"));
ConfigureWidgetForViewportUi(&m_uiMainWindow);
m_uiMainWindow.setVisible(false);
m_uiOverlay.setObjectName(m_uiOverlay.windowTitle());
m_uiOverlay.setObjectName(QString("ViewportUiOverlay"));
m_uiMainWindow.setCentralWidget(&m_uiOverlay);
m_uiOverlay.setVisible(false);

@ -25,8 +25,7 @@ namespace AZ
enum class TangentSpace
{
FromSourceScene = 0,
MikkT = 1,
EMotionFX = 2
MikkT = 1
};
enum class BitangentMethod

@ -34,7 +34,6 @@ namespace AZ
->Method("GetBitangent", &MeshVertexBitangentData::GetBitangent)
->Method("GetBitangentSetIndex", &MeshVertexBitangentData::GetBitangentSetIndex)
->Method("GetTangentSpace", &MeshVertexBitangentData::GetTangentSpace)
->Enum<(int)SceneAPI::DataTypes::TangentSpace::EMotionFX>("EMotionFX")
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
}

@ -34,7 +34,6 @@ namespace AZ
->Method("GetTangent", &MeshVertexTangentData::GetTangent)
->Method("GetTangentSetIndex", &MeshVertexTangentData::GetTangentSetIndex)
->Method("GetTangentSpace", &MeshVertexTangentData::GetTangentSpace)
->Enum<(int)SceneAPI::DataTypes::TangentSpace::EMotionFX>("EMotionFX")
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
}

@ -23,6 +23,7 @@
#include <SceneAPI/SceneData/Rules/MaterialRule.h>
#include <SceneAPI/SceneData/Rules/StaticMeshAdvancedRule.h>
#include <SceneAPI/SceneData/Rules/SkeletonProxyRule.h>
#include <SceneAPI/SceneData/Rules/TangentsRule.h>
#include <SceneAPI/SceneData/Rules/SkinMeshAdvancedRule.h>
#include <SceneAPI/SceneData/Rules/SkinRule.h>
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
@ -82,6 +83,10 @@ namespace AZ
{
modifiers.push_back(azrtti_typeid<CoordinateSystemRule>());
}
if (existingRules.find(SceneData::TangentsRule::TYPEINFO_Uuid()) == existingRules.end())
{
modifiers.push_back(SceneData::TangentsRule::TYPEINFO_Uuid());
}
}
else if (target.RTTI_IsTypeOf(DataTypes::ISkinGroup::TYPEINFO_Uuid()))
{

@ -27,114 +27,14 @@ namespace AZ
TangentsRule::TangentsRule()
: DataTypes::IRule()
, m_tangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT)
, m_bitangentMethod(AZ::SceneAPI::DataTypes::BitangentMethod::Orthogonal)
, m_uvSetIndex(0)
, m_normalize(true)
{
}
AZ::SceneAPI::DataTypes::TangentSpace TangentsRule::GetTangentSpace() const
{
return m_tangentSpace;
}
AZ::SceneAPI::DataTypes::BitangentMethod TangentsRule::GetBitangentMethod() const
{
return m_bitangentMethod;
}
AZ::u64 TangentsRule::GetUVSetIndex() const
{
return m_uvSetIndex;
}
bool TangentsRule::GetNormalizeVectors() const
{
return m_normalize;
}
// Find UV data.
AZ::SceneAPI::DataTypes::IMeshVertexUVData* TangentsRule::FindUVData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 uvSet)
{
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
AZ::u64 uvSetIndex = 0;
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
{
AZ::SceneAPI::DataTypes::IMeshVertexUVData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexUVData*>(child->second.get());
if (data)
{
if (uvSetIndex == uvSet)
{
return data;
}
uvSetIndex++;
}
}
return nullptr;
}
// Find tangent data.
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* TangentsRule::FindTangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace)
{
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
{
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexTangentData*>(child->second.get());
if (data)
{
if (setIndex == data->GetTangentSetIndex() && tangentSpace == data->GetTangentSpace())
{
return data;
}
}
}
return nullptr;
}
// Find bitangent data.
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* TangentsRule::FindBitangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace)
{
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
{
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexBitangentData*>(child->second.get());
if (data)
{
if (setIndex == data->GetBitangentSetIndex() && tangentSpace == data->GetTangentSpace())
{
return data;
}
}
}
return nullptr;
}
AZ::Crc32 TangentsRule::GetNormalizeVisibility() const
{
return (m_tangentSpace == AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX) ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
}
AZ::Crc32 TangentsRule::GetOrthogonalVisibility() const
{
return (m_tangentSpace == AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX) ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
}
void TangentsRule::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
@ -143,11 +43,8 @@ namespace AZ
return;
}
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(2)
->Field("tangentSpace", &TangentsRule::m_tangentSpace)
->Field("bitangentMethod", &TangentsRule::m_bitangentMethod)
->Field("normalize", &TangentsRule::m_normalize)
->Field("uvSetIndex", &TangentsRule::m_uvSetIndex);
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(3)
->Field("tangentSpace", &TangentsRule::m_tangentSpace);
AZ::EditContext* editContext = serializeContext->GetEditContext();
if (editContext)
@ -159,17 +56,7 @@ namespace AZ
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_tangentSpace, "Tangent space", "Specify the tangent space used for normal map baking. Choose 'From Fbx' to extract the tangents and bitangents directly from the Fbx file. When there is no tangents rule or the Fbx has no tangents stored inside it, the 'MikkT' option will be used with orthogonal tangents of unit length, so with the normalize option enabled, using the first UV set.")
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene, "From Source Scene")
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::MikkT, "MikkT")
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX, "EMotion FX")
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_bitangentMethod, "Bitangents", "Set to 'use from tangent space' to use the bitangents generated by the algorithm used or inside the fbx file. This can result in non-orthogonal tangents. Set to 'orthogonal' to skip storing the bitangents and let the engine calculate the bitangents in a way it will be perpendicular to both the normal and tangent.")
->EnumAttribute(AZ::SceneAPI::DataTypes::BitangentMethod::UseFromTangentSpace, "Use from tangent space")
->EnumAttribute(AZ::SceneAPI::DataTypes::BitangentMethod::Orthogonal, "Orthogonal")
->Attribute(AZ::Edit::Attributes::Visibility, &TangentsRule::GetOrthogonalVisibility)
->DataElement(AZ::Edit::UIHandlers::Default, &TangentsRule::m_uvSetIndex, "Uv set", "The UV set index to generate the tangents from. A value of 0 means the first uv set, while 1 means the second uv set.")
->Attribute(AZ::Edit::Attributes::Min, 0)
->Attribute(AZ::Edit::Attributes::Max, 1)
->DataElement(AZ::Edit::UIHandlers::Default, &TangentsRule::m_normalize, "Normalize", "Normalize the tangents and bitangents? When disabled the vectors might no be unit length, which can be useful for relief mapping.")
->Attribute(AZ::Edit::Attributes::Visibility, &TangentsRule::GetNormalizeVisibility)
;
}
}

@ -46,24 +46,11 @@ namespace AZ
SCENE_DATA_API ~TangentsRule() override = default;
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const;
SCENE_DATA_API AZ::SceneAPI::DataTypes::BitangentMethod GetBitangentMethod() const;
SCENE_DATA_API AZ::u64 GetUVSetIndex() const;
SCENE_DATA_API bool GetNormalizeVectors() const;
SCENE_DATA_API static AZ::SceneAPI::DataTypes::IMeshVertexUVData* FindUVData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 uvSet);
SCENE_DATA_API static AZ::SceneAPI::DataTypes::IMeshVertexTangentData* FindTangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace);
SCENE_DATA_API static AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* FindBitangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace);
static void Reflect(ReflectContext* context);
protected:
AZ::Crc32 GetNormalizeVisibility() const;
AZ::Crc32 GetOrthogonalVisibility() const;
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace; /**< Specifies how to handle tangents. Either generate them, or import them. */
AZ::SceneAPI::DataTypes::BitangentMethod m_bitangentMethod; /**< Grab the bitangents from the generator/source or use an orthogonal basis by always calculating them? */
AZ::u64 m_uvSetIndex; /**< Generate the tangents from this UV set. */
bool m_normalize; /**< Normalize the tangent and bitangents? */
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace; /**< Specifies how to handle tangents. Either generate them, or import them. */
};
} // SceneData
} // SceneAPI

@ -94,7 +94,7 @@ namespace AZ
tangentData->AppendTangent(AZ::Vector4{0.12f, 0.34f, 0.56f, 0.78f});
tangentData->AppendTangent(AZ::Vector4{0.18f, 0.28f, 0.19f, 0.29f});
tangentData->AppendTangent(AZ::Vector4{0.21f, 0.43f, 0.65f, 0.87f});
tangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX);
tangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT);
tangentData->SetTangentSetIndex(2);
return true;
}

@ -540,7 +540,9 @@ namespace AZ
}
else
{
AZ_Warning(s_builderName, false, "Found multiple tangent data sets. Only the first will be used.");
AZ_Warning(s_builderName, false,
"Found multiple tangent data sets for mesh '%s'. Only the first will be used.",
content.m_name.GetCStr());
}
}
else if (azrtti_istypeof<BitangentData>(data.get()))
@ -552,7 +554,9 @@ namespace AZ
}
else
{
AZ_Warning(s_builderName, false, "Found multiple bitangent data sets. Only the first will be used.");
AZ_Warning(s_builderName, false,
"Found multiple bitangent data sets for mesh '%s'. Only the first will be used.",
content.m_name.GetCStr());
}
}
else if (azrtti_istypeof<MaterialData>(data.get()))

@ -52,11 +52,8 @@ namespace AZ::SceneGenerationComponents
}
}
AZStd::vector<AZ::SceneAPI::DataTypes::TangentSpace> TangentGenerateComponent::CollectRequiredTangentSpaces(const AZ::SceneAPI::Containers::Scene& scene) const
AZ::SceneAPI::DataTypes::TangentSpace TangentGenerateComponent::GetTangentSpaceFromRule(const AZ::SceneAPI::Containers::Scene& scene) const
{
AZStd::vector<AZ::SceneAPI::DataTypes::TangentSpace> result;
for (const auto& object : scene.GetManifest().GetValueStorage())
{
if (object->RTTI_IsTypeOf(AZ::SceneAPI::DataTypes::IGroup::TYPEINFO_Uuid()))
@ -65,18 +62,14 @@ namespace AZ::SceneGenerationComponents
const AZ::SceneAPI::SceneData::TangentsRule* rule = group->GetRuleContainerConst().FindFirstByType<AZ::SceneAPI::SceneData::TangentsRule>().get();
if (rule)
{
if (AZStd::find(result.begin(), result.end(), rule->GetTangentSpace()) == result.end())
{
result.emplace_back(rule->GetTangentSpace());
}
return rule->GetTangentSpace();
}
}
}
return result;
return AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene;
}
AZ::SceneAPI::Events::ProcessingResult TangentGenerateComponent::GenerateTangentData(TangentGenerateContext& context)
{
// Iterate over all graph content and filter out all meshes.
@ -115,17 +108,15 @@ namespace AZ::SceneGenerationComponents
return AZ::SceneAPI::Events::ProcessingResult::Success;
}
void TangentGenerateComponent::UpdateFbxTangentWValues(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, const AZ::SceneAPI::DataTypes::IMeshData* meshData)
{
// Iterate over all UV sets.
AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData = AZ::SceneAPI::SceneData::TangentsRule::FindUVData(graph, nodeIndex, 0);
AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData = FindUvData(graph, nodeIndex, 0);
size_t uvSetIndex = 0;
while (uvData)
{
// Get the tangents and bitangents from the source scene.
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = FindTangentData(graph, nodeIndex, uvSetIndex);
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = FindBitangentData(graph, nodeIndex, uvSetIndex);
if (fbxTangentData && fbxBitangentData)
{
@ -163,7 +154,7 @@ namespace AZ::SceneGenerationComponents
}
// Find the next UV set.
uvData = AZ::SceneAPI::SceneData::TangentsRule::FindUVData(graph, nodeIndex, ++uvSetIndex);
uvData = FindUvData(graph, nodeIndex, ++uvSetIndex);
}
}
@ -191,148 +182,249 @@ namespace AZ::SceneGenerationComponents
AZ::SceneAPI::Containers::SceneGraph& graph = scene.GetGraph();
// Check if we have any UV data, if not, we cannot possibly generate the tangents.
AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData = AZ::SceneAPI::SceneData::TangentsRule::FindUVData(graph, nodeIndex, 0);
if (!uvData)
const size_t uvSetCount = CalcUvSetCount(graph, nodeIndex);
if (uvSetCount == 0)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::WarningWindow, "We cannot generate tangents for this mesh, as it has no UV coordinates!\n");
AZ_Warning(AZ::SceneAPI::Utilities::WarningWindow, false, "Cannot generate tangents for this mesh, as it has no UV coordinates.\n");
return true; // No fatal error
}
// Check if we had tangents inside the source scene file.
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* fbxTangentData = AZ::SceneAPI::SceneData::TangentsRule::FindTangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* fbxBitangentData = AZ::SceneAPI::SceneData::TangentsRule::FindBitangentData(graph, nodeIndex, 0, AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
// Check what tangent spaces we need.
AZStd::vector<AZ::SceneAPI::DataTypes::TangentSpace> requiredSpaces = CollectRequiredTangentSpaces(scene);
// If we have no tangent rules, so if the required spaces is empty.
if (requiredSpaces.empty())
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Mesh '%s' has no tangents rule, assuming MikkT tangent space on UV set 0, using normalized tangents and orthogonal bitangents!\n", scene.GetGraph().GetNodeName(nodeIndex).GetName());
requiredSpaces.emplace_back(AZ::SceneAPI::DataTypes::TangentSpace::MikkT);
}
// If all we need is import from the source scene, and we have tangent data from the source scene already, then skip generating.
if ((requiredSpaces.size() == 1 && requiredSpaces[0] == AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene) && fbxTangentData && fbxBitangentData)
{
return true;
}
const AZ::SceneAPI::DataTypes::TangentSpace ruleTangentSpace = GetTangentSpaceFromRule(scene);
// Find all blend shape data under the mesh. We need to generate the tangent and bitangent for blend shape as well.
AZStd::vector<AZ::SceneData::GraphData::BlendShapeData*> blendShapes;
FindBlendShapes(graph, nodeIndex, blendShapes);
// Generate all the tangent spaces we need.
// Do this for every UV set.
// Generate tangents/bitangents for all uv sets.
bool allSuccess = true;
size_t uvSetIndex = 0;
while (uvData)
for (size_t uvSetIndex = 0; uvSetIndex < uvSetCount; ++uvSetIndex)
{
for (AZ::SceneAPI::DataTypes::TangentSpace space : requiredSpaces)
AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData = FindUvData(graph, nodeIndex, uvSetIndex);
if (!uvData)
{
switch (space)
AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, "Cannot generate tangents for uv set %zu as it cannot be retrieved.\n", uvSetIndex);
continue;
}
// Check if we had tangents inside the source scene file.
AZ::SceneAPI::DataTypes::TangentSpace tangentSpace = ruleTangentSpace;
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* tangentData = FindTangentData(graph, nodeIndex, uvSetIndex);
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* bitangentData = FindBitangentData(graph, nodeIndex, uvSetIndex);
// If all we need is import from the source scene, and we have tangent data from the source scene already, then skip generating.
if ((tangentSpace == AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene))
{
if (tangentData && bitangentData)
{
// If we want Fbx tangents, we don't need to do anything for that.
case AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene:
AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Using source scene tangents and bitangents for uv set %zu for mesh '%s'.\n",
uvSetIndex, scene.GetGraph().GetNodeName(nodeIndex).GetName());
continue;
}
else
{
allSuccess &= true;
// In case there are no tangents/bitangents while the user selected to use the source ones, default to MikkT.
AZ_Warning(AZ::SceneAPI::Utilities::WarningWindow, false, "Cannot use source scene tangents as there are none in the asset for mesh '%s' for uv set %zu. Defaulting to generating tangents using MikkT.\n",
scene.GetGraph().GetNodeName(nodeIndex).GetName(), uvSetIndex);
tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::MikkT;
}
break;
}
// Generate using MikkT space.
case AZ::SceneAPI::DataTypes::TangentSpace::MikkT:
if (!tangentData)
{
if (!AZ::SceneGenerationComponents::TangentGenerateComponent::CreateTangentLayer(scene.GetManifest(), nodeIndex, meshData->GetVertexCount(), uvSetIndex,
tangentSpace, graph, &tangentData))
{
allSuccess &= AZ::TangentGeneration::Mesh::MikkT::GenerateTangents(
scene.GetManifest(), graph, nodeIndex, const_cast<AZ::SceneAPI::DataTypes::IMeshData*>(meshData), uvSetIndex);
for (AZ::SceneData::GraphData::BlendShapeData* blendShape : blendShapes)
{
allSuccess &= AZ::TangentGeneration::BlendShape::MikkT::GenerateTangents(blendShape, uvSetIndex);
}
AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, "Failed to create tangents data set for mesh %s for uv set %zu.\n",
scene.GetGraph().GetNodeName(nodeIndex).GetName(), uvSetIndex);
continue;
}
break;
}
if (!bitangentData)
{
if (!AZ::SceneGenerationComponents::TangentGenerateComponent::CreateBitangentLayer(scene.GetManifest(), nodeIndex, meshData->GetVertexCount(), uvSetIndex,
tangentSpace, graph, &bitangentData))
{
AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, "Failed to create bitangents data set for mesh %s for uv set %zu.\n",
scene.GetGraph().GetNodeName(nodeIndex).GetName(), uvSetIndex);
continue;
}
}
tangentData->SetTangentSpace(tangentSpace);
bitangentData->SetTangentSpace(tangentSpace);
// If we use EMotion FX calculated tangents, we don't need to generate this here.
case AZ::SceneAPI::DataTypes::TangentSpace::EMotionFX:
allSuccess &= true;
break;
switch (tangentSpace)
{
// Generate using MikkT space.
case AZ::SceneAPI::DataTypes::TangentSpace::MikkT:
{
allSuccess &= AZ::TangentGeneration::Mesh::MikkT::GenerateTangents(meshData, uvData, tangentData, bitangentData);
default:
for (AZ::SceneData::GraphData::BlendShapeData* blendShape : blendShapes)
{
AZ_Assert(false, "Unknown tangent space selected (spaceID=%d) for UV set %d, cannot generate tangents!\n", static_cast<AZ::u32>(space), uvSetIndex);
allSuccess = false;
}
allSuccess &= AZ::TangentGeneration::BlendShape::MikkT::GenerateTangents(blendShape, uvSetIndex);
}
}
break;
// Try to find the next UV set.
uvData = AZ::SceneAPI::SceneData::TangentsRule::FindUVData(graph, nodeIndex, ++uvSetIndex);
default:
{
AZ_Assert(false, "Unknown tangent space selected (spaceID=%d) for UV set %d, cannot generate tangents!\n", static_cast<AZ::u32>(tangentSpace), uvSetIndex);
allSuccess = false;
}
}
}
return allSuccess;
}
size_t TangentGenerateComponent::CalcUvSetCount(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex) const
{
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
size_t result = 0;
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
{
AZ::SceneAPI::DataTypes::IMeshVertexUVData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexUVData*>(child->second.get());
if (data)
{
result++;
}
}
return result;
}
AZ::SceneAPI::DataTypes::IMeshVertexUVData* TangentGenerateComponent::FindUvData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 uvSet) const
{
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
AZ::u64 uvSetIndex = 0;
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
{
AZ::SceneAPI::DataTypes::IMeshVertexUVData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexUVData*>(child->second.get());
if (data)
{
if (uvSetIndex == uvSet)
{
return data;
}
uvSetIndex++;
}
}
return nullptr;
}
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* TangentGenerateComponent::FindTangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex) const
{
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
{
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexTangentData*>(child->second.get());
if (data && setIndex == data->GetTangentSetIndex())
{
return data;
}
}
return nullptr;
}
bool TangentGenerateComponent::CreateTangentBitangentLayers(AZ::SceneAPI::Containers::SceneManifest& manifest, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, size_t numVerts, size_t uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace, const char* spaceName, AZ::SceneAPI::Containers::SceneGraph& graph, AZ::SceneAPI::DataTypes::IMeshVertexTangentData** outTangentData, AZ::SceneAPI::DataTypes::IMeshVertexBitangentData** outBitangentData)
bool TangentGenerateComponent::CreateTangentLayer(AZ::SceneAPI::Containers::SceneManifest& manifest,
const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex,
size_t numVerts,
size_t uvSetIndex,
AZ::SceneAPI::DataTypes::TangentSpace tangentSpace,
AZ::SceneAPI::Containers::SceneGraph& graph,
AZ::SceneAPI::DataTypes::IMeshVertexTangentData** outTangentData)
{
*outTangentData = nullptr;
*outBitangentData = nullptr;
*outTangentData = nullptr;
//-------------------------------------------------------------
// Create tangent layer.
//-------------------------------------------------------------
AZStd::shared_ptr<SceneData::GraphData::MeshVertexTangentData> tangentData = AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexTangentData>();
tangentData->Resize(numVerts);
AZ_Assert(tangentData, "Failed to allocate tangent data for scene graph.");
if (!tangentData)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to allocate tangent data.\n");
AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, "Failed to allocate tangent data.\n");
return false;
}
tangentData->SetTangentSetIndex(uvSetIndex);
tangentData->SetTangentSpace(tangentSpace);
const AZStd::string tangentGeneratedName = AZStd::string::format("TangentSet_%s_%zu", spaceName, uvSetIndex);
const AZStd::string tangentGeneratedName = AZStd::string::format("TangentSet_%zu", uvSetIndex);
const AZStd::string tangentSetName = AZ::SceneAPI::DataTypes::Utilities::CreateUniqueName<SceneData::GraphData::MeshVertexBitangentData>(tangentGeneratedName, manifest);
AZ::SceneAPI::Containers::SceneGraph::NodeIndex newIndex = graph.AddChild(nodeIndex, tangentSetName.c_str(), tangentData);
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for tangent attribute.");
if (!newIndex.IsValid())
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to create node in scene graph that stores tangent data.\n");
AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, "Failed to create node in scene graph that stores tangent data.\n");
return false;
}
graph.MakeEndPoint(newIndex);
//-------------------------------------------------------------
// Create bitangent layer.
//-------------------------------------------------------------
*outTangentData = tangentData.get();
return true;
}
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* TangentGenerateComponent::FindBitangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex) const
{
const auto nameContentView = AZ::SceneAPI::Containers::Views::MakePairView(graph.GetNameStorage(), graph.GetContentStorage());
auto meshChildView = AZ::SceneAPI::Containers::Views::MakeSceneGraphChildView<AZ::SceneAPI::Containers::Views::AcceptEndPointsOnly>(graph, nodeIndex, nameContentView.begin(), true);
for (auto child = meshChildView.begin(); child != meshChildView.end(); ++child)
{
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* data = azrtti_cast<AZ::SceneAPI::DataTypes::IMeshVertexBitangentData*>(child->second.get());
if (data && setIndex == data->GetBitangentSetIndex())
{
return data;
}
}
return nullptr;
}
bool TangentGenerateComponent::CreateBitangentLayer(AZ::SceneAPI::Containers::SceneManifest& manifest,
const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex,
size_t numVerts,
size_t uvSetIndex,
AZ::SceneAPI::DataTypes::TangentSpace tangentSpace,
AZ::SceneAPI::Containers::SceneGraph& graph,
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData** outBitangentData)
{
*outBitangentData = nullptr;
AZStd::shared_ptr<AZ::SceneData::GraphData::MeshVertexBitangentData> bitangentData = AZStd::make_shared<AZ::SceneData::GraphData::MeshVertexBitangentData>();
bitangentData->Resize(numVerts);
AZ_Assert(bitangentData, "Failed to allocate bitangent data for scene graph.");
if (!bitangentData)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to allocate bitangent data.\n");
AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, "Failed to allocate bitangent data.\n");
return false;
}
bitangentData->SetBitangentSetIndex(uvSetIndex);
bitangentData->SetTangentSpace(tangentSpace);
const AZStd::string bitangentGeneratedName = AZStd::string::format("BitangentSet_%s_%zu", spaceName, uvSetIndex);
const AZStd::string bitangentGeneratedName = AZStd::string::format("BitangentSet_%zu", uvSetIndex);
const AZStd::string bitangentSetName = AZ::SceneAPI::DataTypes::Utilities::CreateUniqueName<SceneData::GraphData::MeshVertexBitangentData>(bitangentGeneratedName, manifest);
newIndex = graph.AddChild(nodeIndex, bitangentSetName.c_str(), bitangentData);
AZ::SceneAPI::Containers::SceneGraph::NodeIndex newIndex = graph.AddChild(nodeIndex, bitangentSetName.c_str(), bitangentData);
AZ_Assert(newIndex.IsValid(), "Failed to create SceneGraph node for bitangent attribute.");
if (!newIndex.IsValid())
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to create node in scene graph that stores bitangent data.\n");
AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false, "Failed to create node in scene graph that stores bitangent data.\n");
return false;
}
graph.MakeEndPoint(newIndex);
*outTangentData = tangentData.get();
*outBitangentData = bitangentData.get();
*outBitangentData = bitangentData.get();
return true;
}
} // namespace AZ::SceneGenerationComponents

@ -50,8 +50,6 @@ namespace AZ::SceneGenerationComponents
TangentGenerateComponent();
static void Reflect(AZ::ReflectContext* context);
static bool CreateTangentBitangentLayers(AZ::SceneAPI::Containers::SceneManifest& manifest, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, size_t numVerts, size_t uvSetIndex, AZ::SceneAPI::DataTypes::TangentSpace tangentSpace,
const char* spaceName, AZ::SceneAPI::Containers::SceneGraph& graph, AZ::SceneAPI::DataTypes::IMeshVertexTangentData** outTangentData, AZ::SceneAPI::DataTypes::IMeshVertexBitangentData** outBitangentData);
AZ::SceneAPI::Events::ProcessingResult GenerateTangentData(TangentGenerateContext& context);
@ -61,6 +59,27 @@ namespace AZ::SceneGenerationComponents
AZStd::vector<AZ::SceneData::GraphData::BlendShapeData*>& outBlendShapes) const;
bool GenerateTangentsForMesh(AZ::SceneAPI::Containers::Scene& scene, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::SceneAPI::DataTypes::IMeshData* meshData);
void UpdateFbxTangentWValues(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, const AZ::SceneAPI::DataTypes::IMeshData* meshData);
AZStd::vector<AZ::SceneAPI::DataTypes::TangentSpace> CollectRequiredTangentSpaces(const AZ::SceneAPI::Containers::Scene& scene) const;
AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpaceFromRule(const AZ::SceneAPI::Containers::Scene& scene) const;
size_t CalcUvSetCount(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex) const;
AZ::SceneAPI::DataTypes::IMeshVertexUVData* FindUvData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 uvSet) const;
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* FindTangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex) const;
bool CreateTangentLayer(AZ::SceneAPI::Containers::SceneManifest& manifest,
const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex,
size_t numVerts,
size_t uvSetIndex,
AZ::SceneAPI::DataTypes::TangentSpace tangentSpace,
AZ::SceneAPI::Containers::SceneGraph& graph,
AZ::SceneAPI::DataTypes::IMeshVertexTangentData** outTangentData);
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* FindBitangentData(AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::u64 setIndex) const;
bool CreateBitangentLayer(AZ::SceneAPI::Containers::SceneManifest& manifest,
const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex,
size_t numVerts,
size_t uvSetIndex,
AZ::SceneAPI::DataTypes::TangentSpace tangentSpace,
AZ::SceneAPI::Containers::SceneGraph& graph,
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData** outBitangentData);
};
} // namespace AZ::SceneGenerationComponents

@ -32,7 +32,6 @@ namespace AZ::TangentGeneration::Mesh::MikkT
return customData->m_meshData->GetFaceCount();
}
int GetNumVerticesOfFace(const SMikkTSpaceContext* context, const int face)
{
AZ_UNUSED(context);
@ -40,7 +39,6 @@ namespace AZ::TangentGeneration::Mesh::MikkT
return 3;
}
void GetPosition(const SMikkTSpaceContext* context, float posOut[], const int face, const int vert)
{
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
@ -51,7 +49,6 @@ namespace AZ::TangentGeneration::Mesh::MikkT
posOut[2] = pos.GetZ();
}
void GetNormal(const SMikkTSpaceContext* context, float normOut[], const int face, const int vert)
{
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
@ -62,7 +59,6 @@ namespace AZ::TangentGeneration::Mesh::MikkT
normOut[2] = normal.GetZ();
}
void GetTexCoord(const SMikkTSpaceContext* context, float texOut[], const int face, const int vert)
{
MikktCustomData* customData = static_cast<MikktCustomData*>(context->m_pUserData);
@ -72,7 +68,6 @@ namespace AZ::TangentGeneration::Mesh::MikkT
texOut[1] = uv.GetY();
}
// This function is used to return the tangent and signValue to the application.
// tangent is a unit length vector.
// For normal maps it is sufficient to use the following simplified version of the bitangent which is generated at pixel/vertex level.
@ -91,7 +86,6 @@ namespace AZ::TangentGeneration::Mesh::MikkT
customData->m_bitangentData->SetBitangent(vertexIndex, bitangent);
}
// This function is used to return tangent space results to the application.
// tangent and bitangent are unit length vectors and magS and magT are their
// true magnitudes which can be used for relief mapping effects.
@ -111,27 +105,11 @@ namespace AZ::TangentGeneration::Mesh::MikkT
customData->m_bitangentData->SetBitangent(vertexIndex, bitangentVec);
}
bool GenerateTangents(AZ::SceneAPI::Containers::SceneManifest& manifest, AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::SceneAPI::DataTypes::IMeshData* meshData, size_t uvSet)
bool GenerateTangents(const AZ::SceneAPI::DataTypes::IMeshData* meshData,
const AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData,
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* outTangentData,
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* outBitangentData)
{
// Create tangent and bitangent data sets and relate them to the given UV set.
AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData = AZ::SceneAPI::SceneData::TangentsRule::FindUVData(graph, nodeIndex, uvSet);
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* tangentData = nullptr;
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* bitangentData = nullptr;
if (!uvData)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Cannot find UV data (set index=%d) to generate tangents and bitangents from in MikkT generator!\n", uvSet);
return false;
}
if (!AZ::SceneGenerationComponents::TangentGenerateComponent::CreateTangentBitangentLayers(manifest, nodeIndex, meshData->GetVertexCount(), uvSet, AZ::SceneAPI::DataTypes::TangentSpace::MikkT, "MikkT", graph, &tangentData, &bitangentData))
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to create tangents and bitangents data sets inside MikkT generator!\n");
return false;
}
//----------------------------------
// Provide the MikkT interface.
SMikkTSpaceInterface mikkInterface;
mikkInterface.m_getNumFaces = GetNumFaces;
@ -146,8 +124,8 @@ namespace AZ::TangentGeneration::Mesh::MikkT
MikktCustomData customData;
customData.m_meshData = meshData;
customData.m_uvData = uvData;
customData.m_tangentData = tangentData;
customData.m_bitangentData = bitangentData;
customData.m_tangentData = outTangentData;
customData.m_bitangentData = outBitangentData;
// Generate the tangents.
SMikkTSpaceContext mikkContext;
@ -155,7 +133,7 @@ namespace AZ::TangentGeneration::Mesh::MikkT
mikkContext.m_pUserData = &customData;
if (genTangSpaceDefault(&mikkContext) == 0)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to generate tangents and bitangents using MikkT, because MikkT reported failure!\n");
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Failed to generate tangents and bitangents using MikkT.\n");
return false;
}

@ -19,12 +19,14 @@ namespace AZ::TangentGeneration::Mesh::MikkT
{
struct MikktCustomData
{
AZ::SceneAPI::DataTypes::IMeshData* m_meshData;
AZ::SceneAPI::DataTypes::IMeshVertexUVData* m_uvData;
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* m_tangentData;
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* m_bitangentData;
const AZ::SceneAPI::DataTypes::IMeshData* m_meshData;
const AZ::SceneAPI::DataTypes::IMeshVertexUVData* m_uvData;
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* m_tangentData;
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* m_bitangentData;
};
// The main generation method.
bool GenerateTangents(AZ::SceneAPI::Containers::SceneManifest& manifest, AZ::SceneAPI::Containers::SceneGraph& graph, const AZ::SceneAPI::Containers::SceneGraph::NodeIndex& nodeIndex, AZ::SceneAPI::DataTypes::IMeshData* meshData, size_t uvSet);
bool GenerateTangents(const AZ::SceneAPI::DataTypes::IMeshData* meshData,
const AZ::SceneAPI::DataTypes::IMeshVertexUVData* uvData,
AZ::SceneAPI::DataTypes::IMeshVertexTangentData* outTangentData,
AZ::SceneAPI::DataTypes::IMeshVertexBitangentData* outBitangentData);
} // namespace AZ::TangentGeneration::MikkT

Loading…
Cancel
Save