update joints to use cluster viewport ui. (#4352)

also some joints Component mode cleanup.

Signed-off-by: amzn-sean <75276488+amzn-sean@users.noreply.github.com>
This commit is contained in:
amzn-sean
2021-09-30 13:39:22 +01:00
committed by GitHub
parent 9eb9a13d99
commit 43748c37fd
77 changed files with 3006 additions and 3026 deletions
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M16.9,16.7c0,0.7-0.6,1.3-1.3,1.3h-7c-0.7,0-1.3-0.6-1.3-1.3v-0.5h-2v0.5c0,1.8,1.5,3.3,3.3,3.3h2
c-0.2,0.5-0.1,1.2,0.3,1.6c0.6,0.6,1.5,0.6,2.1,0c0.4-0.4,0.5-1,0.3-1.6h2.3c1.8,0,3.3-1.5,3.3-3.3v-0.5l-2,0V16.7z M12.3,20.9
c-0.2,0.2-0.6,0.2-0.8,0c-0.2-0.2-0.2-0.5,0-0.8c0.2-0.2,0.5-0.2,0.8,0c0,0,0,0,0,0C12.5,20.3,12.5,20.7,12.3,20.9z"/>
<rect x="6.5" y="8" transform="matrix(0.9939 -0.1101 0.1101 0.9939 -0.8771 1.3776)" class="st0" width="11" height="1.4"/>
<rect x="6.5" y="10.6" transform="matrix(0.9939 -0.1101 0.1101 0.9939 -1.1681 1.3937)" class="st0" width="11" height="1.4"/>
<rect x="6.5" y="13.2" transform="matrix(0.9939 -0.1101 0.1101 0.9939 -1.4588 1.4055)" class="st0" width="11" height="1.4"/>
<path class="st0" d="M13.3,4c0.1-0.2,0.1-0.3,0.1-0.5c0-0.8-0.6-1.4-1.4-1.4s-1.4,0.6-1.4,1.4c0,0.2,0,0.4,0.1,0.5H5.2v2.3h13.6V4
H13.3z M12,4c-0.3,0-0.6-0.3-0.6-0.6c0-0.3,0.3-0.6,0.6-0.6s0.6,0.3,0.6,0.6C12.6,3.7,12.3,4,12,4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M3,17.9v1.3c5.9,1.2,12.1,1.2,18,0v-1.3C15.1,19.1,8.9,19.1,3,17.9z"/>
<path class="st0" d="M3,15.9v1.3c5.9,1.2,12.1,1.2,18,0v-1.3C15.1,17.2,8.9,17.2,3,15.9z"/>
<path class="st0" d="M3,14v1.3c5.9,1.2,12.1,1.2,18-0.1v-1.3C15.1,15.2,8.9,15.3,3,14z"/>
<path class="st0" d="M6.5,11.5c0.1,0.1,0.2,0.2,0.4,0.2c0.1,0,0.3-0.1,0.4-0.2l2-2.1c0.2-0.2,0.2-0.5,0-0.8c-0.2-0.2-0.5-0.2-0.7,0
c0,0,0,0,0,0L7.4,9.9V3.3C7.4,3.2,7.3,3,7.2,3c0,0,0,0,0,0H6.7C6.5,3,6.4,3.1,6.4,3.3v0.2v6.4L5.3,8.7C5,8.5,4.7,8.5,4.5,8.7
C4.4,8.8,4.4,8.9,4.3,9.1c0,0.1,0.1,0.3,0.2,0.4L6.5,11.5z"/>
<path class="st0" d="M16.7,11.5c0.1,0.1,0.2,0.2,0.4,0.2c0.1,0,0.3-0.1,0.4-0.2l2-2.1c0.2-0.2,0.2-0.5,0-0.8
c-0.2-0.2-0.5-0.2-0.7,0c0,0,0,0,0,0l-1.1,1.1V3.3c0-0.2-0.1-0.3-0.2-0.3c0,0,0,0,0,0h-0.5c-0.2,0-0.3,0.1-0.3,0.3v0.2v6.4
l-1.1-1.2c-0.2-0.2-0.6-0.2-0.8,0c-0.1,0.1-0.1,0.2-0.1,0.4c0,0.1,0.1,0.3,0.1,0.4L16.7,11.5z"/>
<path class="st0" d="M9.6,11.3l2,2.1c0.1,0.1,0.2,0.2,0.4,0.2c0.1,0,0.3-0.1,0.4-0.2l2-2.1c0.2-0.2,0.2-0.5,0-0.8c0,0,0,0,0,0
c-0.2-0.2-0.5-0.2-0.7,0c0,0,0,0,0,0l-1.1,1.1V5.1c0-0.2-0.1-0.3-0.3-0.3c0,0,0,0,0,0h-0.5c-0.2,0-0.3,0.1-0.3,0.3v0.1v6.4
l-1.1-1.1c-0.2-0.2-0.5-0.2-0.7,0c0,0,0,0,0,0c-0.1,0.1-0.2,0.2-0.2,0.4C9.4,11,9.5,11.2,9.6,11.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M12,12.2c-5.9,0-7-1.6-7-1.6v7.2c0.1,1,3,1.9,6.7,1.9V21c0,0.2,0.1,0.3,0.3,0.3s0.3-0.1,0.3-0.3v-1.3
c3.6,0,6.5-0.9,6.7-1.9v-7.2C19,10.6,17.9,12.2,12,12.2z"/>
<path class="st0" d="M12.3,7.6V6.9l0.8,0.4V6.6c2.7-0.1,5.2-0.7,5.2-1.4c0-0.8-2.7-1.2-6-1.2V3c0-0.2-0.1-0.3-0.3-0.3
c-0.2,0-0.3,0.1-0.3,0.3v1c-3.3,0-6,0.4-6,1.2c0,0.2,0.5,0.4,0.8,0.5C7.2,5.9,8,6.1,8.8,6.1c0.3,0,0.5,0,0.8,0C9.4,6,9.2,6,9,6
C7.6,5.9,7.2,5.5,7.2,5.2c0-0.5,1.8-0.7,4.4-0.7v1.1l-1,0.5l1,0.5v1.1C8,7.7,5,8.5,5,9.6c0,1.1,3.1,2,7,2s7-0.9,7-2
C19,8.5,16,7.7,12.3,7.6z M12.3,4.6c2.6,0,4.5,0.2,4.5,0.7c0,0.5-1.7,0.6-3.6,0.7v-1l-0.9,0.4V4.6z M8.4,9.6c0-0.5,1.4-0.9,3.2-1v2
C9.8,10.6,8.4,10.1,8.4,9.6z M12.3,10.6v-2c1.8,0,3.2,0.5,3.2,1C15.6,10.1,14.2,10.6,12.3,10.6z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M19.6,11.7l-2.2-2.2l0,0l-1.7-1.7l0,0h0l0,0l0,0h0l0,0L13.4,10l-0.1,0.1l0,0l0,0l1.7,1.7l0,0l1.6,1.6
c1,0.8,1.1,2.2,0.4,3.2c-0.3,0.3-0.8,0.5-1.2,0.5c-0.7,0-1.5-0.3-2-0.8l-1.6-1.6l0,0L10.5,13l-0.7,0.7l-1.7,1.7l3.9,3.9
c2.2,2,5.6,1.7,7.6-0.5C21.3,16.7,21.3,13.7,19.6,11.7z M18.4,18.5c-1.6,1.4-4.1,1.4-5.7,0l-2.2-2.2l0.9-0.9L13,17
c0.7,0.7,1.7,1.1,2.7,1.1c0.7,0,1.5-0.3,2-0.8c1.2-1.4,1-3.5-0.3-4.7l-1.6-1.6l0.9-0.9l2.2,2.2C20.4,14.2,20.2,16.9,18.4,18.5z"/>
<polygon class="st0" points="6.1,7.5 5.1,7.5 5.1,5.9 3,8 5.1,10.1 5.1,8.5 6.1,8.5 "/>
<polygon class="st0" points="7.5,6.1 8.5,6.1 8.5,5.1 10.1,5.1 8,3 5.9,5.1 7.5,5.1 "/>
<polygon class="st0" points="8.5,11 8.5,10 7.5,10 7.5,10.9 5.9,10.9 8,13 10.1,11 "/>
<polygon class="st0" points="10,7.5 10,8.5 10.9,8.5 10.9,10.1 13,8 10.9,5.9 11,7.5 "/>
<rect x="6.5" y="6.5" class="st0" width="3" height="3"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M19.6,11.7l-2.2-2.2l0,0l-1.7-1.7l0,0h0l0,0l0,0h0l0,0L13.4,10l-0.1,0.1l0,0l0,0l1.7,1.7l0,0l1.6,1.6
c1,0.8,1.1,2.2,0.4,3.2c-0.3,0.3-0.8,0.5-1.2,0.5c-0.7,0-1.5-0.3-2-0.8l-1.6-1.6l0,0L10.5,13l-0.7,0.7l-1.7,1.7l3.9,3.9
c2.2,2,5.6,1.7,7.6-0.5C21.3,16.7,21.3,13.7,19.6,11.7z M18.4,18.5c-1.6,1.4-4.1,1.4-5.7,0l-2.2-2.2l0.9-0.9L13,17
c0.7,0.7,1.7,1.1,2.7,1.1c0.7,0,1.5-0.3,2-0.8c1.2-1.4,1-3.5-0.3-4.7l-1.6-1.6l0.9-0.9l2.2,2.2C20.4,14.2,20.2,16.9,18.4,18.5z"/>
<path class="st0" d="M7.1,9.5l2.1,2.1v-1.2c2.3-0.3,4-1.4,4-3.4c0-2.3-2.2-3.5-5-3.5s-5,1.2-5,3.5c0,0.5,0.2,1.1,0.6,1.5
C4.3,9,5,9.4,5.8,9.5c0.4,0.1,0.6,0.2,0.6,0.1S6.2,9.4,5.9,9.2C5,8.9,4.4,8,4.5,7c0-1.4,1.5-2,3.7-2S12,5.6,12,7
c0,1.2-1.1,2-2.8,2.2V7.4L7.1,9.5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M14.5,11.3L14.5,11.3c-0.1,0-0.2,0-0.3,0.1c-0.2,0.1-0.4,0.2-0.6,0.4c-0.5,0.4-1,0.6-1.6,0.7
c-0.6-0.1-1.2-0.4-1.6-0.7c-0.2-0.1-0.4-0.3-0.6-0.4c-0.1,0-0.2-0.1-0.3-0.1H9.5c-2.4,0-3,1-3,1c-0.1,0.2-0.2,0.3-0.3,0.5v1.5
c0,0.4,0.5,0.8,0.5,0.8l1.6,1.6c0.5,0.5,0.8,1.3,0.9,2V21c0,0.4,0.3,0.7,0.7,0.7c0,0,0,0,0,0h4.1c0.4,0,0.7-0.3,0.7-0.7
c0,0,0,0,0,0v-2.3c0-0.7,0.3-1.5,0.9-2l1.6-1.6c0,0,0.5-0.4,0.5-0.8v-1.5c-0.1-0.2-0.2-0.4-0.3-0.5C17.5,12.3,16.9,11.3,14.5,11.3z
"/>
<path class="st0" d="M9.5,10.3c0.2,0,0.3,0.1,0.5,0.1c0.6,0.3,1.3,1.1,2.1,1.1s1.5-0.8,2.1-1.1c0.1-0.1,0.3-0.1,0.5-0.1
c2.7,0,3.3,1.1,3.3,1.1V11c0-0.6-0.3-1.2-0.7-1.7l-1.5-1.6c-0.5-0.7-0.7-1.5-0.7-2.4V3c0-0.6-0.4-1-1-1h-3.8c-0.6,0-1,0.4-1,1v2.3
C9.1,6.2,8.9,7,8.4,7.7L6.9,9.3C6.5,9.7,6.2,10.4,6.2,11v0.5C6.2,11.5,6.8,10.3,9.5,10.3z"/>
<path class="st0" d="M19.6,7.8c-0.1-0.2-0.3-0.2-0.5-0.1C19,7.7,18.9,7.9,19,8.1c1.4,2.5,1.4,5.4,0,7.9c0,0,0,0,0,0
c-0.1,0.2,0,0.4,0.1,0.4c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3-0.1C21.1,13.7,21.1,10.4,19.6,7.8z"/>
<path class="st0" d="M4.1,11.7c0-1.2,0.3-2.4,0.8-3.4c0.1-0.2,0-0.4-0.2-0.4C4.5,7.8,4.3,7.8,4.3,8c-1.2,2.5-1.1,5.4,0.2,7.8
C4.5,15.9,4.6,16,4.7,16c0,0,0.1,0,0.1,0c0,0,0,0,0,0C5,15.9,5.1,15.7,5,15.5C4.4,14.3,4.1,13,4.1,11.7z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M19.3,10.7l0.1-2.5c0-0.2-0.2-0.4-0.4-0.4c-0.3,0-0.5,0.2-0.5,0.5l-0.1,1.6L18,9.5l0,0
c-0.1-0.1-0.2-0.2-0.2-0.2c-0.4-0.4-0.9-0.7-1.3-0.9L17,6.7c0.1-0.3,0-0.6-0.3-0.7c0,0-0.1,0-0.1,0l-3.1-0.6
c-0.3-0.1-0.6,0.1-0.7,0.4c0,0,0,0.1,0,0.1l-0.1,1.4C10.3,7,7.9,7.8,6,9.5l0,0L5.6,9.8V8.2c0-0.3-0.2-0.5-0.5-0.5c0,0,0,0,0,0
c-0.2,0-0.5,0.2-0.5,0.4c0,0,0,0,0,0v2.5c0,0.3,0.2,0.5,0.5,0.5l2.5,0.1c0.3,0,0.5-0.2,0.5-0.5c0-0.3-0.2-0.5-0.5-0.5l-1.5-0.1
C6.3,10,6.4,9.8,6.6,9.7c1.8-1.5,4-2.1,6.1-1.9l-0.1,1.9c0,0.4,0.3,0.7,0.6,0.8l0.3,0.1l-1.8,9.2c-0.6,0.1-1.1,0.6-1.1,1.2
c0,0.7,0.6,1.3,1.3,1.3s1.3-0.6,1.3-1.3c0-0.4-0.2-0.8-0.6-1l1.8-9.2l0.3,0.1c0.4,0.1,0.7-0.1,0.9-0.5l0.5-1.4
c0.6,0.3,1.1,0.7,1.6,1.2l0.1,0.1c0,0,0.1,0.1,0.1,0.1h-1.6c-0.1,0-0.3,0-0.3,0.1c-0.1,0.1-0.1,0.2-0.2,0.3c0,0.2,0.2,0.4,0.4,0.5
c0,0,0,0,0,0h2.5C19.1,11.2,19.3,11,19.3,10.7z"/>
<path class="st0" d="M2.8,10.1c-0.1-0.1-0.3-0.1-0.4,0c-0.1,0.1-0.1,0.3,0,0.4l2.9,2.7c0.1,0,0.1,0.1,0.2,0.1c0.1,0,0.2,0,0.2-0.1
c0.1-0.1,0.1-0.3,0-0.4L2.8,10.1z"/>
<path class="st0" d="M21.5,10c-0.1-0.1-0.3-0.1-0.4,0l-2.7,2.9c0,0.1-0.1,0.1-0.1,0.2c0,0.1,0,0.1,0.1,0.2c0.1,0.1,0.3,0.1,0.4,0
l2.6-2.9C21.6,10.3,21.6,10.1,21.5,10z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M17.5,18.1c-0.1,0-0.1,0-0.2,0H6.9l7.4-7.3c0.3-0.2,0.3-0.6,0-0.9c0,0,0,0,0,0c-0.1-0.1-0.3-0.2-0.5-0.2
c-0.2,0-0.3,0.1-0.5,0.2L6,17.2V6.9c0-0.4-0.3-0.7-0.7-0.7C5,6.2,4.7,6.5,4.7,6.9c0,0,0,0,0,0L4.6,17.1c0,0,0,0,0,0
c-1.3,0-2.3,1-2.3,2.3s1,2.3,2.3,2.3s2.3-1,2.3-2.3h10.4c0.4,0,0.7-0.2,0.7-0.6C18.1,18.5,17.9,18.1,17.5,18.1z"/>
<path class="st0" d="M21.8,13.2c-0.2-0.2-0.6-0.2-0.9,0l-1.3,1.3V14c-0.1-5.2-4.3-9.4-9.5-9.4H9.6l1.3-1.2c0.2-0.2,0.2-0.6,0-0.9
c-0.1-0.1-0.3-0.2-0.4-0.2c-0.2,0-0.3,0.1-0.4,0.2L7.7,4.8C7.6,4.9,7.5,5.1,7.5,5.2c0,0.2,0.1,0.3,0.2,0.4l2.3,2.3
c0.2,0.2,0.6,0.2,0.9,0c0.2-0.2,0.2-0.6,0-0.8L9.6,5.8h0.5c4.6,0,8.3,3.6,8.3,8.2c0,0,0,0,0,0v0.5l-1.3-1.3
c-0.1-0.1-0.3-0.2-0.4-0.2c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.2-0.2,0.6,0,0.8c0,0,0,0,0,0l2.4,2.3c0.2,0.2,0.6,0.2,0.9,0l2.3-2.3
C22.1,13.8,22.1,13.4,21.8,13.2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -390,6 +390,14 @@
<file>img/UI20/toolbar/Y_axis.svg</file>
<file>img/UI20/toolbar/Z_axis.svg</file>
<file>img/UI20/toolbar/XY2_copy.svg</file>
<file>img/UI20/toolbar/joints/Damping.svg</file>
<file>img/UI20/toolbar/joints/MaxForce.svg</file>
<file>img/UI20/toolbar/joints/MaxTorque.svg</file>
<file>img/UI20/toolbar/joints/SnapPosition.svg</file>
<file>img/UI20/toolbar/joints/SnapRotation.svg</file>
<file>img/UI20/toolbar/joints/Stiffness.svg</file>
<file>img/UI20/toolbar/joints/SwingLimits.svg</file>
<file>img/UI20/toolbar/joints/TwistLimits.svg</file>
<file>img/triangle0.png</file>
<file>img/triangle0_highlighted.png</file>
<file>img/line.png</file>
@@ -29,13 +29,29 @@ namespace AzToolsFramework::ViewportUi::Internal
void ButtonGroup::SetHighlightedButton(ButtonId buttonId)
{
if (buttonId == m_highlightedButtonId) // the requested button is highlighted, so do nothing.
{
return;
}
if (auto buttonEntry = m_buttons.find(buttonId); buttonEntry != m_buttons.end())
{
for (auto& button : m_buttons)
{
button.second->m_state = Button::State::Deselected;
}
ClearHighlightedButton();
buttonEntry->second->m_state = Button::State::Selected;
m_highlightedButtonId = buttonId;
}
}
void ButtonGroup::ClearHighlightedButton()
{
if (m_highlightedButtonId == InvalidButtonId)
{
return;
}
if (auto buttonEntry = m_buttons.find(m_highlightedButtonId); buttonEntry != m_buttons.end())
{
buttonEntry->second->m_state = Button::State::Deselected;
m_highlightedButtonId = InvalidButtonId;
}
}
@@ -25,6 +25,7 @@ namespace AzToolsFramework::ViewportUi::Internal
~ButtonGroup() = default;
void SetHighlightedButton(ButtonId buttonId);
void ClearHighlightedButton();
void SetViewportUiElementId(ViewportUiElementId id);
ViewportUiElementId GetViewportUiElementId() const;
@@ -40,5 +41,6 @@ namespace AzToolsFramework::ViewportUi::Internal
AZ::Event<ButtonId> m_buttonTriggeredEvent;
ViewportUiElementId m_viewportUiId;
AZStd::unordered_map<ButtonId, AZStd::unique_ptr<Button>> m_buttons;
ButtonId m_highlightedButtonId = InvalidButtonId;
};
} // namespace AzToolsFramework::ViewportUi::Internal
@@ -50,6 +50,16 @@ namespace AzToolsFramework::ViewportUi
}
}
void ViewportUiManager::ClearClusterActiveButton(ClusterId clusterId)
{
if (auto clusterIt = m_clusterButtonGroups.find(clusterId); clusterIt != m_clusterButtonGroups.end())
{
auto cluster = clusterIt->second;
cluster->ClearHighlightedButton();
UpdateButtonGroupUi(cluster.get());
}
}
void ViewportUiManager::SetSwitcherActiveButton(const SwitcherId switcherId, const ButtonId buttonId)
{
if (auto switcherIt = m_switcherButtonGroups.find(switcherId); switcherIt != m_switcherButtonGroups.end())
@@ -30,6 +30,7 @@ namespace AzToolsFramework::ViewportUi
const ClusterId CreateCluster(Alignment align) override;
const SwitcherId CreateSwitcher(Alignment align) override;
void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) override;
void ClearClusterActiveButton(ClusterId clusterId) override;
void SetSwitcherActiveButton(SwitcherId switcherId, ButtonId buttonId) override;
void SetClusterButtonLocked(ClusterId clusterId, ButtonId buttonId, bool isLocked) override;
void SetClusterButtonTooltip(ClusterId clusterId, ButtonId buttonId, const AZStd::string& tooltip) override;
@@ -59,6 +59,8 @@ namespace AzToolsFramework::ViewportUi
virtual const SwitcherId CreateSwitcher(Alignment align) = 0;
//! Sets the active button of the cluster. This is the button which will display as highlighted.
virtual void SetClusterActiveButton(ClusterId clusterId, ButtonId buttonId) = 0;
//! Clears the active button of the cluster if one is active. The button will no longer display as highlighted.
virtual void ClearClusterActiveButton(ClusterId clusterId) = 0;
//! Sets the active button of the switcher. This is the button which has a text label.
virtual void SetSwitcherActiveButton(SwitcherId clusterId, ButtonId buttonId) = 0;
//! Adds a locked overlay to the cluster button's icon.
@@ -127,6 +127,25 @@ namespace UnitTest
EXPECT_TRUE(button->m_state == AzToolsFramework::ViewportUi::Internal::Button::State::Selected);
}
TEST_F(ViewportUiManagerTestFixture, ClearClusterActiveButtonSetsButtonStateToDeselected)
{
// setup
auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft);
auto buttonId = m_viewportManagerWrapper.GetViewportManager()->CreateClusterButton(clusterId, "");
auto clusterEntry = m_viewportManagerWrapper.GetViewportManager()->GetClusterMap().find(clusterId);
auto button = clusterEntry->second->GetButton(buttonId);
// first set a button to active
m_viewportManagerWrapper.GetViewportManager()->SetClusterActiveButton(clusterId, buttonId);
EXPECT_TRUE(button->m_state == AzToolsFramework::ViewportUi::Internal::Button::State::Selected);
// clear the active button on the cluster
m_viewportManagerWrapper.GetViewportManager()->ClearClusterActiveButton(clusterId);
// the button should now be deselected
EXPECT_TRUE(button->m_state == AzToolsFramework::ViewportUi::Internal::Button::State::Deselected);
}
TEST_F(ViewportUiManagerTestFixture, RegisterClusterEventHandlerConnectsHandlerToClusterEvent)
{
auto clusterId = m_viewportManagerWrapper.GetViewportManager()->CreateCluster(AzToolsFramework::ViewportUi::Alignment::TopLeft);
@@ -8,21 +8,20 @@
#pragma once
#include "ColliderSubComponentMode.h"
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <AzToolsFramework/Manipulators/ScaleManipulators.h>
namespace PhysX
{
/// Sub component mode for modifying the asset scale on a collider in the viewport.
class ColliderAssetScaleMode
: public PhysX::ColliderSubComponentMode
class ColliderAssetScaleMode : public PhysXSubComponentModeBase
{
public:
AZ_CLASS_ALLOCATOR_DECL
ColliderAssetScaleMode();
// ColliderSubComponentMode ...
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
+3 -4
View File
@@ -8,19 +8,18 @@
#pragma once
#include "ColliderSubComponentMode.h"
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <AzToolsFramework/ComponentModes/BoxViewportEdit.h>
namespace PhysX
{
/// Sub component mode for modifying the box dimensions on a collider.
class ColliderBoxMode
: public PhysX::ColliderSubComponentMode
class ColliderBoxMode : public PhysXSubComponentModeBase
{
public:
AZ_CLASS_ALLOCATOR_DECL
// ColliderSubComponentMode ...
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
+3 -3
View File
@@ -8,7 +8,7 @@
#pragma once
#include "ColliderSubComponentMode.h"
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <AzToolsFramework/ComponentModes/BoxViewportEdit.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
@@ -16,13 +16,13 @@ namespace PhysX
{
/// Sub component mode for modifying the height and radius on a capsule collider.
class ColliderCapsuleMode
: public PhysX::ColliderSubComponentMode
: public PhysXSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
AZ_CLASS_ALLOCATOR_DECL
// ColliderSubComponentMode ...
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
@@ -7,7 +7,6 @@
*/
#include "ColliderComponentMode.h"
#include "ColliderSubComponentMode.h"
#include "ColliderOffsetMode.h"
#include "ColliderRotationMode.h"
#include "ColliderBoxMode.h"
@@ -15,6 +14,7 @@
#include "ColliderCapsuleMode.h"
#include "ColliderAssetScaleMode.h"
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <PhysX/EditorColliderComponentRequestBus.h>
#include <AzFramework/Physics/ShapeConfiguration.h>
@@ -15,7 +15,7 @@
namespace PhysX
{
class ColliderSubComponentMode;
class PhysXSubComponentModeBase;
//! ComponentMode for the Collider Component - Manages a list of Sub-Component Modes and
//! is responsible for switching between and activating them.
@@ -53,7 +53,7 @@ namespace PhysX
void CreateSubModes();
void ResetCurrentMode();
AZStd::unordered_map<SubMode, AZStd::unique_ptr<ColliderSubComponentMode>> m_subModes;
AZStd::unordered_map<SubMode, AZStd::unique_ptr<PhysXSubComponentModeBase>> m_subModes;
SubMode m_subMode = SubMode::Dimensions;
//! Create the Viewport UI cluster for sub mode selection.
+3 -4
View File
@@ -8,21 +8,20 @@
#pragma once
#include "ColliderSubComponentMode.h"
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
namespace PhysX
{
/// Sub component mode for modifying offset on a collider in the viewport.
class ColliderOffsetMode
: public PhysX::ColliderSubComponentMode
class ColliderOffsetMode : public PhysXSubComponentModeBase
{
public:
AZ_CLASS_ALLOCATOR_DECL
ColliderOffsetMode();
// ColliderSubComponentMode ...
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
@@ -8,7 +8,7 @@
#pragma once
#include "ColliderSubComponentMode.h"
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <AzToolsFramework/Manipulators/RotationManipulators.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
@@ -16,7 +16,7 @@ namespace PhysX
{
/// Sub component mode for modifying the rotation on a collider in the viewport.
class ColliderRotationMode
: public PhysX::ColliderSubComponentMode
: public PhysXSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
@@ -24,7 +24,7 @@ namespace PhysX
ColliderRotationMode();
// ColliderSubComponentMode ...
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
+3 -3
View File
@@ -8,7 +8,7 @@
#pragma once
#include "ColliderSubComponentMode.h"
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <AzToolsFramework/ComponentModes/BoxViewportEdit.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
@@ -16,13 +16,13 @@ namespace PhysX
{
/// Sub component mode for modifying the box dimensions on a collider.
class ColliderSphereMode
: public PhysX::ColliderSubComponentMode
: public PhysXSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
AZ_CLASS_ALLOCATOR_DECL
// ColliderSubComponentMode ...
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
@@ -1,42 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
namespace AZ
{
class EntityComponentIdPair;
}
namespace PhysX
{
/// Interface to implement when adding a new editing mode
/// for collider component mode.
class ColliderSubComponentMode
{
public:
virtual ~ColliderSubComponentMode() {};
/// Called when the mode is entered to initialise the mode.
/// @param idPair The entity/component id pair.
virtual void Setup(const AZ::EntityComponentIdPair& idPair) = 0;
/// Called when the mode needs to refresh it's values.
/// @param idPair The entity/component id pair.
virtual void Refresh(const AZ::EntityComponentIdPair& idPair) = 0;
/// Called when the mode exits to perform cleanup.
/// @param idPair The entity/component id pair.
virtual void Teardown(const AZ::EntityComponentIdPair& idPair) = 0;
/// Called when reset hotkey is pressed.
/// Should reset values in the sub component mode to sensible defaults.
/// @param idPair The entity/component id pair.
virtual void ResetValues(const AZ::EntityComponentIdPair& idPair) = 0;
};
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/std/utils.h>
namespace PhysX
{
//! Pair of floating point values for angular limits.
using AngleLimitsFloatPair = AZStd::pair<float, float>;
} // namespace PhysX
@@ -1,577 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/EditorJointConfiguration.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/EditorSubComponentModeAngleCone.h>
#include <Editor/EditorSubComponentModeAnglePair.h>
#include <Editor/EditorSubComponentModeLinear.h>
#include <Editor/EditorSubComponentModeRotation.h>
#include <Editor/EditorSubComponentModeSnapPosition.h>
#include <Editor/EditorSubComponentModeSnapRotation.h>
#include <Editor/EditorSubComponentModeVec3.h>
#include <PhysX/EditorJointBus.h>
namespace PhysX
{
namespace
{
//! Uri's for shortcut actions.
const AZ::Crc32 GoToNextModeActionUri = AZ_CRC("com.o3de.action.physx.joint.nextmode", 0xe9cf4ed6);
const AZ::Crc32 GoToPrevModeActionUri = AZ_CRC("com.o3de.action.physx.joint.prevmode", 0xe70f8daa);
}
const AZStd::string EditorJointComponentMode::s_parameterAngularPair = "Twist Limits";
const AZStd::string EditorJointComponentMode::s_parameterDamping = "Damping";
const AZStd::string EditorJointComponentMode::s_parameterMaxForce = "Maximum Force";
const AZStd::string EditorJointComponentMode::s_parameterMaxTorque = "Maximum Torque";
const AZStd::string EditorJointComponentMode::s_parameterPosition = "Position";
const AZStd::string EditorJointComponentMode::s_parameterRotation = "Rotation";
const AZStd::string EditorJointComponentMode::s_parameterSnapPosition = "Snap Position";
const AZStd::string EditorJointComponentMode::s_parameterSnapRotation = "Snap Rotation";
const AZStd::string EditorJointComponentMode::s_parameterStiffness = "Stiffness";
const AZStd::string EditorJointComponentMode::s_parameterSwingLimit = "Swing Limits";
const AZStd::string EditorJointComponentMode::s_parameterTolerance = "Tolerance";
const AZStd::string EditorJointComponentMode::s_parameterTransform = "Transform";
const AZStd::string EditorJointComponentMode::s_parameterComponentMode = "Component Mode";
const AZStd::string EditorJointComponentMode::s_parameterLeadEntity = "Lead Entity";
const AZStd::string EditorJointComponentMode::s_parameterSelectOnSnap = "Select on Snap";
EditorSubComponentModeConfig::EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type)
: m_name(name), m_type(type)
{
}
EditorSubComponentModeConfig::EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type
, float exponent
, float max
, float min)
: m_name(name), m_type(type), m_exponent(exponent), m_max(max), m_min(min)
{
}
EditorSubComponentModeConfig::EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type
, const AZ::Vector3& axis
, float max
, float min)
: m_name(name), m_type(type), m_axis(axis), m_max(max), m_min(min)
{
}
EditorSubComponentModeConfig::EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type
, float max
, float min)
: m_name(name), m_type(type), m_max(max), m_min(min)
{
}
EditorJointComponentMode::EditorJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType)
: EditorBaseComponentMode(entityComponentIdPair, componentType)
, m_entityComponentIdPair(entityComponentIdPair)
, m_componentType(componentType)
{
EditorJointRequestBus::Event(
m_entityComponentIdPair
, &EditorJointRequests::SetBoolValue
, EditorJointComponentMode::s_parameterComponentMode
, true);
}
EditorJointComponentMode::~EditorJointComponentMode()
{
EditorJointRequestBus::Event(
m_entityComponentIdPair
, &EditorJointRequests::SetBoolValue
, EditorJointComponentMode::s_parameterComponentMode
, false);
}
bool EditorJointComponentMode::HandleMouseInteraction(
const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
if (mouseInteraction.m_mouseEvent == AzToolsFramework::ViewportInteraction::MouseEvent::Wheel &&
mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl())
{
NextMode();
return true;
}
// Propagate mouse interaction to sub-component mode.
if (m_currentSubComponentMode)
{
m_currentSubComponentMode->HandleMouseInteraction(mouseInteraction);
}
return false;
}
AZStd::vector<AzToolsFramework::ActionOverride> EditorJointComponentMode::PopulateActionsImpl()
{
AzToolsFramework::ActionOverride goToNextMode;
goToNextMode.SetUri(GoToNextModeActionUri);
goToNextMode.SetKeySequence(QKeySequence(Qt::Key_Tab));
goToNextMode.SetTitle("Next Mode");
goToNextMode.SetTip("Go to next mode");
goToNextMode.SetEntityComponentIdPair(GetEntityComponentIdPair());
goToNextMode.SetCallback([this]()
{
NextMode();
});
AzToolsFramework::ActionOverride goToPrevMode;
goToPrevMode.SetUri(GoToPrevModeActionUri);
goToPrevMode.SetKeySequence(QKeySequence(Qt::SHIFT + Qt::Key_Tab));
goToPrevMode.SetTitle("Previous Mode");
goToPrevMode.SetTip("Go to previous mode");
goToPrevMode.SetEntityComponentIdPair(GetEntityComponentIdPair());
goToPrevMode.SetCallback([this]()
{
PreviousMode();
});
return {goToNextMode, goToPrevMode};
}
void EditorJointComponentMode::NextMode()
{
const bool isForwardChange = true;
ChangeMode(isForwardChange);
}
void EditorJointComponentMode::PreviousMode()
{
const bool isForwardChange = false;
ChangeMode(isForwardChange);
}
void EditorJointComponentMode::ChangeMode(bool forwardChange)
{
if (m_configMap.empty())
{
return;
}
AZStd::string previousModeName;
if (m_currentSubComponentMode)
{
previousModeName = m_currentSubComponentMode->m_name;
m_currentSubComponentMode.reset();
}
ConfigMapIter configIter = m_configMap.begin();
if (!previousModeName.empty())
{
configIter = m_configMap.find(previousModeName);
}
AZ::u32 iterCount = 0;
do
{
if (forwardChange)
{
++configIter;
if (configIter == m_configMap.end())
{
configIter = m_configMap.begin();
}
}
else
{
if (configIter == m_configMap.begin())
{
configIter = m_configMap.end();
}
--configIter;
}
++iterCount;
} while (!IsSubComponentModeUsed(configIter->second.m_name) && iterCount != m_configMap.size());
if (iterCount == m_configMap.size()) // All sub component modes are not in use.
{
return;
}
SetCurrentSubComponentMode(configIter->second.m_name);
}
void EditorJointComponentMode::SetCurrentSubComponentMode(const AZStd::string& subComponentModeName)
{
ConfigMapIter configIter = m_configMap.find(subComponentModeName);
if (configIter == m_configMap.end())
{
AZ_Warning("EditorJointComponentMode"
, false
, "Attempt to set sub component mode which does not exist: %s"
, subComponentModeName.c_str());
return;
}
EditorSubComponentModeConfig config = configIter->second;
EditorJointRequestBus::EventResult(
config.m_selectLeadOnSnap, m_entityComponentIdPair
, &EditorJointRequests::GetBoolValue
, s_parameterSelectOnSnap);
m_currentSubComponentMode.reset();
switch (config.m_type)
{
case EditorSubComponentModeType::Linear:
SetSubComponentModeLinear(config);
break;
case EditorSubComponentModeType::AnglePair:
SetSubComponentModeAnglePair(config);
break;
case EditorSubComponentModeType::AngleCone:
SetSubComponentModeAngleCone(config);
break;
case EditorSubComponentModeType::Vec3:
SetSubComponentModeVec3(config);
break;
case EditorSubComponentModeType::Rotation:
SetSubComponentModeRotation(config);
break;
case EditorSubComponentModeType::SnapPosition:
SetSubComponentModeSnapPosition(config);
break;
case EditorSubComponentModeType::SnapRotation:
SetSubComponentModeSnapRotation(config);
break;
default:
AZ_Error("EditorJointComponentMode::SetCurrentSubComponentMode"
, false
, "Unsupported sub-component mode type.");
}
}
bool EditorJointComponentMode::IsSubComponentModeUsed(const AZStd::string& subComponentModeName)
{
bool isUsed = false;
EditorJointRequestBus::EventResult(
isUsed, m_entityComponentIdPair
, &EditorJointRequests::IsParameterUsed
, subComponentModeName);
return isUsed;
}
void EditorJointComponentMode::SetSubComponentModeAngleCone(const EditorSubComponentModeConfig& config)
{
m_currentSubComponentMode = AZStd::make_shared<EditorSubComponentModeAngleCone>(m_entityComponentIdPair
, m_componentType
, config.m_name
, config.m_max
, config.m_min);
}
void EditorJointComponentMode::SetSubComponentModeAnglePair(const EditorSubComponentModeConfig& config)
{
m_currentSubComponentMode = AZStd::make_shared<EditorSubComponentModeAnglePair>(m_entityComponentIdPair
, m_componentType
, config.m_name
, config.m_axis
, config.m_max
, config.m_min
, config.m_min
, -config.m_max);
}
void EditorJointComponentMode::SetSubComponentModeLinear(const EditorSubComponentModeConfig& config)
{
m_currentSubComponentMode = AZStd::make_shared<EditorSubComponentModeLinear>(m_entityComponentIdPair
, m_componentType
, config.m_name
, config.m_exponent
, config.m_max
, config.m_min);
}
void EditorJointComponentMode::SetSubComponentModeVec3(const EditorSubComponentModeConfig& config)
{
m_currentSubComponentMode = AZStd::make_shared<EditorSubComponentModeVec3>(m_entityComponentIdPair
, m_componentType
, config.m_name);
}
void EditorJointComponentMode::SetSubComponentModeRotation(const EditorSubComponentModeConfig& config)
{
m_currentSubComponentMode = AZStd::make_shared<EditorSubComponentModeRotation>(m_entityComponentIdPair
, m_componentType
, config.m_name);
}
void EditorJointComponentMode::SetSubComponentModeSnapPosition(const EditorSubComponentModeConfig& config)
{
m_currentSubComponentMode = AZStd::make_shared<EditorSubComponentModeSnapPosition>(m_entityComponentIdPair
, m_componentType
, config.m_name
, config.m_selectLeadOnSnap);
}
void EditorJointComponentMode::SetSubComponentModeSnapRotation(const EditorSubComponentModeConfig& config)
{
m_currentSubComponentMode = AZStd::make_shared<EditorSubComponentModeSnapRotation>(m_entityComponentIdPair
, m_componentType
, config.m_name);
}
EditorBallJointComponentMode::EditorBallJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType)
: EditorJointComponentMode(entityComponentIdPair, componentType)
{
m_configMap = Configure();
NextMode();
}
EditorBallJointComponentMode::~EditorBallJointComponentMode()
{
if (m_currentSubComponentMode)
{
m_currentSubComponentMode.reset();
}
}
void EditorJointComponentMode::Refresh()
{
if (m_currentSubComponentMode)
{
m_currentSubComponentMode->Refresh();
}
}
AZStd::map<AZStd::string, EditorSubComponentModeConfig> EditorBallJointComponentMode::Configure()
{
AZStd::map<AZStd::string, EditorSubComponentModeConfig> configMap;
configMap.emplace(
EditorJointComponentMode::s_parameterPosition
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterPosition
, EditorSubComponentModeType::Vec3)
);
configMap.emplace(
EditorJointComponentMode::s_parameterRotation
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterRotation
, EditorSubComponentModeType::Rotation)
);
configMap.emplace(
EditorJointComponentMode::s_parameterSnapPosition
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterSnapPosition
, EditorSubComponentModeType::SnapPosition)
);
configMap.emplace(
EditorJointComponentMode::s_parameterSnapRotation
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterSnapRotation
, EditorSubComponentModeType::SnapRotation)
);
const float exponentBreakage = 1.0f;
configMap.emplace(
EditorJointComponentMode::s_parameterMaxForce
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterMaxForce
, EditorSubComponentModeType::Linear
, exponentBreakage
, PhysX::EditorJointConfig::s_breakageMax
, PhysX::EditorJointConfig::s_breakageMin)
);
configMap.emplace(
EditorJointComponentMode::s_parameterMaxTorque
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterMaxTorque
, EditorSubComponentModeType::Linear
, exponentBreakage
, PhysX::EditorJointConfig::s_breakageMax
, PhysX::EditorJointConfig::s_breakageMin)
);
const float exponentSpring = 2.0f;
configMap.emplace(
EditorJointComponentMode::s_parameterDamping
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterDamping
, EditorSubComponentModeType::Linear
, exponentSpring
, PhysX::EditorJointLimitConeConfig::s_springMax
, PhysX::EditorJointLimitConeConfig::s_springMin)
);
configMap.emplace(
EditorJointComponentMode::s_parameterStiffness
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterStiffness
, EditorSubComponentModeType::Linear
, exponentSpring
, PhysX::EditorJointLimitConeConfig::s_springMax
, PhysX::EditorJointLimitConeConfig::s_springMin)
);
// Cone tip to base is always X-axis.
//The angle cone defines the limitations for rotation about the Y and Z axes.
configMap.emplace(
EditorJointComponentMode::s_parameterSwingLimit
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterSwingLimit
, EditorSubComponentModeType::AngleCone
, PhysX::EditorJointLimitConeConfig::s_angleMax
, PhysX::EditorJointLimitConeConfig::s_angleMin)
);
return configMap;
}
EditorFixedJointComponentMode::EditorFixedJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType)
: EditorJointComponentMode(entityComponentIdPair, componentType)
{
m_configMap = Configure();
NextMode();
}
EditorFixedJointComponentMode::~EditorFixedJointComponentMode()
{
if (m_currentSubComponentMode)
{
m_currentSubComponentMode.reset();
}
}
AZStd::map<AZStd::string, EditorSubComponentModeConfig> EditorFixedJointComponentMode::Configure()
{
AZStd::map<AZStd::string, EditorSubComponentModeConfig> configMap;
configMap.emplace(
EditorJointComponentMode::s_parameterPosition
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterPosition
, EditorSubComponentModeType::Vec3)
);
configMap.emplace(
EditorJointComponentMode::s_parameterRotation
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterRotation
, EditorSubComponentModeType::Rotation)
);
const float exponentBreakage = 1.0f;
configMap.emplace(
EditorJointComponentMode::s_parameterMaxForce
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterMaxForce
, EditorSubComponentModeType::Linear
, exponentBreakage
, PhysX::EditorJointConfig::s_breakageMax
, PhysX::EditorJointConfig::s_breakageMin)
);
configMap.emplace(
EditorJointComponentMode::s_parameterMaxTorque
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterMaxTorque
, EditorSubComponentModeType::Linear
, exponentBreakage
, PhysX::EditorJointConfig::s_breakageMax
, PhysX::EditorJointConfig::s_breakageMin)
);
return configMap;
}
EditorHingeJointComponentMode::EditorHingeJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType)
: EditorJointComponentMode(entityComponentIdPair, componentType)
{
m_configMap = Configure();
NextMode();
}
EditorHingeJointComponentMode::~EditorHingeJointComponentMode()
{
if (m_currentSubComponentMode)
{
m_currentSubComponentMode.reset();
}
}
AZStd::map<AZStd::string, EditorSubComponentModeConfig> EditorHingeJointComponentMode::Configure()
{
AZStd::map<AZStd::string, EditorSubComponentModeConfig> configMap;
configMap.emplace(
EditorJointComponentMode::s_parameterPosition
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterPosition
, EditorSubComponentModeType::Vec3)
);
configMap.emplace(
EditorJointComponentMode::s_parameterRotation
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterRotation
, EditorSubComponentModeType::Rotation)
);
const float exponentBreakage = 1.0f;
configMap.emplace(
EditorJointComponentMode::s_parameterMaxForce
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterMaxForce
, EditorSubComponentModeType::Linear
, exponentBreakage
, PhysX::EditorJointConfig::s_breakageMax
, PhysX::EditorJointConfig::s_breakageMin)
);
configMap.emplace(
EditorJointComponentMode::s_parameterMaxTorque
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterMaxTorque
, EditorSubComponentModeType::Linear
, exponentBreakage
, PhysX::EditorJointConfig::s_breakageMax
, PhysX::EditorJointConfig::s_breakageMin)
);
const float exponentSpring = 2.0f;
configMap.emplace(
EditorJointComponentMode::s_parameterDamping
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterDamping
, EditorSubComponentModeType::Linear
, exponentSpring
, PhysX::EditorJointLimitPairConfig::s_springMax
, PhysX::EditorJointLimitPairConfig::s_springMin)
);
configMap.emplace(
EditorJointComponentMode::s_parameterStiffness
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterStiffness
, EditorSubComponentModeType::Linear
, exponentSpring
, PhysX::EditorJointLimitPairConfig::s_springMax
, PhysX::EditorJointLimitPairConfig::s_springMin)
);
AZ::Vector3 axis = AZ::Vector3::CreateAxisX(); // PhysX revolute joints uses the x-axis by default
configMap.emplace(
EditorJointComponentMode::s_parameterAngularPair
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterAngularPair
, EditorSubComponentModeType::AnglePair
, axis
, PhysX::EditorJointLimitPairConfig::s_angleMax
, PhysX::EditorJointLimitPairConfig::s_angleMin)
);
configMap.emplace(
EditorJointComponentMode::s_parameterSnapPosition
, EditorSubComponentModeConfig(EditorJointComponentMode::s_parameterSnapPosition
, EditorSubComponentModeType::SnapPosition)
);
return configMap;
}
} // namespace LmbrCentral
@@ -1,173 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/std/containers/map.h>
#include <AzToolsFramework/ComponentMode/EditorBaseComponentMode.h>
#include <Editor/EditorSubComponentModeBase.h>
namespace PhysX
{
enum class EditorSubComponentModeType : AZ::u8
{
Linear, /// sub-component mode to modify a single linear value, e.g. a float value.
AnglePair, /// sub-component mode to modify a pair of float values representing angles.
AngleCone, /// sub-component mode to modify a constraint's swing limits and local transformation.
Rotation, /// sub-component mode to modify local transformation.
SnapPosition, /// sub-component mode to modify local position using a point-and-snap feature in the viewport.
SnapRotation, /// sub-component mode to modify local rotation using a point-and-snap feature in the viewport.
Vec3 /// sub-component mode to modify a Vector3 value.
};
/// Contains configuration of a sub-component mode. Shared by different types of sub-component mode.
/// Alternative implementation of this struct using AZStd::Variant is pending the development of the rest of the joint types.
struct EditorSubComponentModeConfig
{
EditorSubComponentModeConfig() = default;
EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type);
EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type
, float exponent
, float max
, float min);
EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type
, const AZ::Vector3& axis
, float max
, float min);
EditorSubComponentModeConfig(const AZStd::string& name
, EditorSubComponentModeType type
, float max
, float min);
AZStd::string m_name;
EditorSubComponentModeType m_type;
AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX();
float m_exponent = 1.0f;
float m_max = FLT_MAX;
float m_min = -FLT_MAX;
bool m_selectLeadOnSnap = true; ///< A user may use the snap-to-position component mode to snap the position of a joint to an entity. This flag indicates if the snapped-to entity would be selected as a joint's lead when that happens.
};
/// Generic component mode that supports multiple sub-component modes.
class EditorJointComponentMode
: public AzToolsFramework::ComponentModeFramework::EditorBaseComponentMode
{
public:
static const AZStd::string s_parameterAngularPair;
static const AZStd::string s_parameterDamping;
static const AZStd::string s_parameterMaxForce;
static const AZStd::string s_parameterMaxTorque;
static const AZStd::string s_parameterPosition;
static const AZStd::string s_parameterRotation;
static const AZStd::string s_parameterSnapPosition;
static const AZStd::string s_parameterSnapRotation;
static const AZStd::string s_parameterStiffness;
static const AZStd::string s_parameterSwingLimit;
static const AZStd::string s_parameterTolerance;
static const AZStd::string s_parameterTransform;
static const AZStd::string s_parameterComponentMode;
static const AZStd::string s_parameterLeadEntity;
static const AZStd::string s_parameterSelectOnSnap;
EditorJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType);
~EditorJointComponentMode();
// EditorBaseComponentMode
void Refresh() override;
/// Returns map of sub-component mode configurations required by this component mode.
virtual AZStd::map<AZStd::string, EditorSubComponentModeConfig> Configure() = 0;
protected:
/// AzToolsFramework::ViewportInteraction::MouseViewportRequests
bool HandleMouseInteraction(
const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
/// EditorBaseComponentMode
AZStd::vector<AzToolsFramework::ActionOverride> PopulateActionsImpl() override;
/// Changes to the next sub-component mode found in m_configMap.
void NextMode();
/// Changes to the previous sub-component mode found in m_configMap.
void PreviousMode();
/// Changes to the next or previous sub-component mode found in m_configMap.
void ChangeMode(bool forwardChange);
/// Replaces m_currentSubComponentMode with a new one instantiated using the configuration identified by the input subComponentModeName.
void SetCurrentSubComponentMode(const AZStd::string& subComponentModeName);
AZStd::shared_ptr<EditorSubComponentModeBase> m_currentSubComponentMode = nullptr; ///< The active sub-component mode in this component mode.
AZ::Uuid m_componentType = AZ::Uuid::CreateNull();
AZStd::map<AZStd::string, EditorSubComponentModeConfig> m_configMap; ///< Contains sub-component mode configurations supported by this component mode.
AZ::EntityComponentIdPair m_entityComponentIdPair;
private:
bool IsSubComponentModeUsed(const AZStd::string& subComponentModeName);
void SetSubComponentModeAngleCone(const EditorSubComponentModeConfig& config);
void SetSubComponentModeAnglePair(const EditorSubComponentModeConfig& config);
void SetSubComponentModeLinear(const EditorSubComponentModeConfig& config);
void SetSubComponentModeVec3(const EditorSubComponentModeConfig& config);
void SetSubComponentModeRotation(const EditorSubComponentModeConfig& config);
void SetSubComponentModeSnapPosition(const EditorSubComponentModeConfig& config);
void SetSubComponentModeSnapRotation(const EditorSubComponentModeConfig& config);
};
/// Ball joint specific component mode. Configure() is overriden to set up the required sub-component modes.
class EditorBallJointComponentMode
: public EditorJointComponentMode
{
public:
EditorBallJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType);
~EditorBallJointComponentMode();
// EditorJointComponentMode
AZStd::map<AZStd::string, EditorSubComponentModeConfig> Configure() override;
};
/// Fixed joint specific component mode. Configure() is overriden to set up the required sub-component modes.
class EditorFixedJointComponentMode
: public EditorJointComponentMode
{
public:
EditorFixedJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType);
~EditorFixedJointComponentMode();
// EditorJointComponentMode
AZStd::map<AZStd::string, EditorSubComponentModeConfig> Configure() override;
};
/// Hinge joint specific component mode. Configure() is overriden to set up the required sub-component modes.
class EditorHingeJointComponentMode
: public EditorJointComponentMode
{
public:
EditorHingeJointComponentMode(
const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Uuid& componentType);
~EditorHingeJointComponentMode();
// EditorJointComponentMode
AZStd::map<AZStd::string, EditorSubComponentModeConfig> Configure() override;
};
using ConfigMap = AZStd::map<AZStd::string, EditorSubComponentModeConfig>;
using ConfigMapIter = ConfigMap::iterator;
using ConfigMapReverseIter = ConfigMap::reverse_iterator;
} // namespace PhysX
@@ -1,68 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <Editor/EditorJointTypeDrawer.h>
namespace PhysX
{
EditorJointTypeDrawer::EditorJointTypeDrawer(EditorJointType jointType,
AzFramework::EntityContextId entityContextId,
const AZStd::string& subComponentModeName):
m_subComponentModeName(subComponentModeName)
{
AzFramework::ViewportDebugDisplayEventBus::Handler::BusConnect(entityContextId);
EditorJointTypeDrawerBus::Handler::BusConnect(EditorJointTypeDrawerId(jointType,
EditorSubComponentModeNameCrc(subComponentModeName)));
}
EditorJointTypeDrawer::~EditorJointTypeDrawer()
{
EditorJointTypeDrawerBus::Handler::BusDisconnect();
AzFramework::ViewportDebugDisplayEventBus::Handler::BusDisconnect();
}
void EditorJointTypeDrawer::DisplayViewport2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
{
const AZ::u32 stateBefore = debugDisplay.GetState();
const AzFramework::CameraState cameraState = AzToolsFramework::GetCameraState(viewportInfo.m_viewportId);
const float xOffsetCurrentMode = 125.0f;
const float yOffsetCurrentMode = 55.0f;
const float xOffsetHotKeys = 125.0f;
const float yOffsetHotKeys = 30.0f;
const float viewportWidthHalf = cameraState.m_viewportSize.GetX() / 2.0f;
const float viewportHeight = cameraState.m_viewportSize.GetY();
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, 1.0f));
AZStd::string screenTextCurrentMode = "Edit mode: " + m_subComponentModeName;
float xPos = viewportWidthHalf - xOffsetCurrentMode;
float yPos = viewportHeight - yOffsetCurrentMode;
float textSize = 2.0f;
debugDisplay.Draw2dTextLabel(xPos, yPos, textSize, screenTextCurrentMode.c_str());
AZStd::string screenTextHotKeys = "<Tab> or <Shift+Tab> to change modes";
xPos = viewportWidthHalf - xOffsetHotKeys;
yPos = viewportHeight - yOffsetHotKeys;
textSize = 1.2f;
debugDisplay.Draw2dTextLabel(xPos, yPos, textSize, screenTextHotKeys.c_str());
debugDisplay.SetState(stateBefore);
}
AZStd::shared_ptr<EditorJointTypeDrawer> EditorJointTypeDrawer::GetEditorJointTypeDrawer()
{
return shared_from_this();
}
} // namespace PhysX
@@ -1,41 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/std/smart_ptr/enable_shared_from_this.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <Editor/EditorJointTypeDrawerBus.h>
namespace PhysX
{
/// This class enables drawing in the viewport once for the component modes of multiple components in one entity.
/// Until the component mode framework allows a way to do this, a work-around like this class is necessary.
/// An instance of this class is created for each pair of component type and sub-component mode.
class EditorJointTypeDrawer
: public EditorJointTypeDrawerBus::Handler
, public AZStd::enable_shared_from_this<EditorJointTypeDrawer>
, private AzFramework::ViewportDebugDisplayEventBus::Handler
{
public:
EditorJointTypeDrawer(EditorJointType id,
AzFramework::EntityContextId entityContextId,
const AZStd::string& subComponentModeName);
~EditorJointTypeDrawer();
private:
// AzFramework::ViewportDebugDisplayEventBus
void DisplayViewport2d(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
// PhysX::EditorJointTypeDrawerBus
AZStd::shared_ptr<EditorJointTypeDrawer> GetEditorJointTypeDrawer() override;
AZStd::string m_subComponentModeName;///< Name of the sub component mode. E.g. Position, Rotation, Snap Position, etc.
};
} // namespace PhysX
@@ -1,31 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace PhysX
{
class EditorJointTypeDrawer;
using EditorJointType = AZ::Uuid;
using EditorSubComponentModeNameCrc = AZ::Crc32;
using EditorJointTypeDrawerId = AZStd::pair<EditorJointType, EditorSubComponentModeNameCrc>;
/// The sub-component mode of a component type uses this bus (by invoking GetEditorJointTypeDrawer) to retrieve a drawer.
/// If nothing is returned, it creates an instance of the drawer that will be shared by other instances of the same component type.
class EditorJointTypeDrawerRequests : public AZ::EBusTraits
{
public:
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = EditorJointTypeDrawerId;
virtual AZStd::shared_ptr<EditorJointTypeDrawer> GetEditorJointTypeDrawer() = 0;
};
using EditorJointTypeDrawerBus = AZ::EBus<EditorJointTypeDrawerRequests>;
} // namespace PhysX
@@ -1,453 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Component/TransformBus.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/EditorSubComponentModeAngleCone.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace
{
const float ArrowLength = 2.0f;
const float ConeHeight = 3.0f;
const float XRotationManipulatorRadius = 2.0f;
const float XRotationManipulatorWidth = 0.05f;
}
namespace PhysX
{
struct SharedRotationState
{
AZ::Vector3 m_axis;
AZ::Quaternion m_savedOrientation = AZ::Quaternion::CreateIdentity();
AngleLimitsFloatPair m_valuePair;
};
EditorSubComponentModeAngleCone::EditorSubComponentModeAngleCone(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, float max
, float min)
: EditorSubComponentModeBase(entityComponentIdPair, componentType, name)
, m_max(max)
, m_min(min)
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
// Initialize manipulators used to resize the base of the cone.
m_yLinearManipulator = AzToolsFramework::LinearManipulator::MakeShared(worldTransform);
m_yLinearManipulator->AddEntityComponentIdPair(m_entityComponentId);
m_yLinearManipulator->SetAxis(AZ::Vector3::CreateAxisZ());
m_zLinearManipulator = AzToolsFramework::LinearManipulator::MakeShared(worldTransform);
m_zLinearManipulator->AddEntityComponentIdPair(m_entityComponentId);
m_zLinearManipulator->SetAxis(AZ::Vector3::CreateAxisY());
m_yzPlanarManipulator = AzToolsFramework::PlanarManipulator::MakeShared(worldTransform);
m_yzPlanarManipulator->AddEntityComponentIdPair(m_entityComponentId);
m_yzPlanarManipulator->SetAxes(AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
ConfigureLinearView(ArrowLength
, AZ::Color(1.0f, 0.0f, 0.0f, 1.0f)
, AZ::Color(0.0f, 1.0f, 0.0f, 1.0f)
, AZ::Color(0.0f, 0.0f, 1.0f, 1.0f));
ConfigurePlanarView(AZ::Color(0.0f, 1.0f, 0.0f, 1.0f)
, AZ::Color(0.0f, 0.0f, 1.0f, 1.0f));
// Position and orientate manipulators
AZ::Transform displacementTransform = localTransform;
AZ::Vector3 displacementTranslate = localRotation.TransformVector(AZ::Vector3(ConeHeight, 0.0f, 0.0f));
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_yLinearManipulator->SetLocalTransform(displacementTransform);
m_zLinearManipulator->SetLocalTransform(displacementTransform);
m_yzPlanarManipulator->SetLocalTransform(displacementTransform);
// Initialize rotation manipulator for rotating cone
m_xRotationManipulator = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_xRotationManipulator->AddEntityComponentIdPair(m_entityComponentId);
m_xRotationManipulator->SetAxis(AZ::Vector3::CreateAxisX());
m_xRotationManipulator->SetLocalTransform(localTransform);
const AZ::Color xRotationManipulatorColor = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
m_xRotationManipulator->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_xRotationManipulator, xRotationManipulatorColor,
XRotationManipulatorRadius, XRotationManipulatorWidth, AzToolsFramework::DrawHalfDottedCircle));
AZStd::shared_ptr<SharedRotationState> sharedRotationState =
AZStd::make_shared<SharedRotationState>();
struct SharedState
{
AngleLimitsFloatPair m_startValues;
};
auto sharedState = AZStd::make_shared<SharedState>();
m_yLinearManipulator->InstallLeftMouseDownCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& /*action*/) mutable
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
sharedState->m_startValues = currentValue;
});
m_yLinearManipulator->InstallMouseMoveCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& action)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
const float axisDisplacement = action.LocalPositionOffset().Dot(localRotation.TransformVector(action.m_fixed.m_axis));
const float originalBaseY = tan(AZ::DegToRad(sharedState->m_startValues.first)) * ConeHeight;
const float newBaseY = originalBaseY + axisDisplacement;
const float newAngle = AZ::GetClamp(AZ::RadToDeg(atan(newBaseY / ConeHeight)), m_min, m_max);
EditorJointRequestBus::Event(
m_entityComponentId
, &EditorJointRequests::SetLinearValuePair
, m_name
, AngleLimitsFloatPair(newAngle, sharedState->m_startValues.second));
m_yLinearManipulator->SetBoundsDirty();
});
m_zLinearManipulator->InstallLeftMouseDownCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& /*action*/) mutable
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
sharedState->m_startValues = currentValue;
});
m_zLinearManipulator->InstallMouseMoveCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& action)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
const float axisDisplacement = action.LocalPositionOffset().Dot(localRotation.TransformVector(action.m_fixed.m_axis));
const float originalBaseZ = tan(AZ::DegToRad(sharedState->m_startValues.second)) * ConeHeight;
const float newBaseZ = originalBaseZ + axisDisplacement;
const float newAngle = AZ::GetClamp(AZ::RadToDeg(atan(newBaseZ / ConeHeight)), m_min, m_max);
EditorJointRequestBus::Event(
m_entityComponentId
, &EditorJointRequests::SetLinearValuePair
, m_name
, AngleLimitsFloatPair(sharedState->m_startValues.first, newAngle));
m_zLinearManipulator->SetBoundsDirty();
});
m_yzPlanarManipulator->InstallLeftMouseDownCallback(
[this, sharedState](const AzToolsFramework::PlanarManipulator::Action& /*action*/) mutable
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
sharedState->m_startValues = currentValue;
});
m_yzPlanarManipulator->InstallMouseMoveCallback(
[this, sharedState](const AzToolsFramework::PlanarManipulator::Action& action)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
const float axisDisplacementY = action.LocalPositionOffset().Dot(localRotation.TransformVector(AZ::Vector3::CreateAxisY()));
const float axisDisplacementZ = action.LocalPositionOffset().Dot(localRotation.TransformVector(AZ::Vector3::CreateAxisZ()));
const float axisDisplacement = axisDisplacementZ > axisDisplacementY? axisDisplacementZ : axisDisplacementY;
const float originalBaseY = tan(AZ::DegToRad(sharedState->m_startValues.first)) * ConeHeight;
const float newBaseY = originalBaseY + axisDisplacement;
const float newAngleY = AZ::GetClamp(AZ::RadToDeg(atan(newBaseY / ConeHeight)), m_min, m_max);
const float originalBaseZ = tan(AZ::DegToRad(sharedState->m_startValues.second)) * ConeHeight;
const float newBaseZ = originalBaseZ + axisDisplacement;
const float newAngleZ = AZ::GetClamp(AZ::RadToDeg(atan(newBaseZ / ConeHeight)), m_min, m_max);
EditorJointRequestBus::Event(
m_entityComponentId
, &EditorJointRequests::SetLinearValuePair
, m_name
, AngleLimitsFloatPair(newAngleY, newAngleZ));
m_yzPlanarManipulator->SetBoundsDirty();
});
struct SharedStateXRotate
{
AZ::Transform m_startTM;
};
auto sharedStateXRotate = AZStd::make_shared<SharedStateXRotate>();
auto mouseDownCallback = [this, sharedRotationState](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
AZ::Quaternion normalizedStart = action.m_start.m_rotation.GetNormalized();
sharedRotationState->m_axis = AZ::Vector3(normalizedStart.GetX(), normalizedStart.GetY(), normalizedStart.GetZ());
sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity();
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
sharedRotationState->m_valuePair = currentValue;
};
auto mouseDownRotateXCallback = [this, sharedStateXRotate]([[maybe_unused]] const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
PhysX::EditorJointRequestBus::EventResult(sharedStateXRotate->m_startTM
, m_entityComponentId
, &PhysX::EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
};
m_xRotationManipulator->InstallLeftMouseDownCallback(mouseDownRotateXCallback);
m_xRotationManipulator->InstallMouseMoveCallback(
[this, sharedStateXRotate]
(const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
AZ::Transform newTransform = AZ::Transform::CreateIdentity();
newTransform = sharedStateXRotate->m_startTM * AZ::Transform::CreateFromQuaternion(action.m_current.m_delta);
PhysX::EditorJointRequestBus::Event(m_entityComponentId
, &PhysX::EditorJointRequests::SetVector3Value
, PhysX::EditorJointComponentMode::s_parameterPosition
, newTransform.GetTranslation());
PhysX::EditorJointRequestBus::Event(m_entityComponentId
, &PhysX::EditorJointRequests::SetVector3Value
, PhysX::EditorJointComponentMode::s_parameterRotation
, newTransform.GetRotation().GetEulerDegrees());
m_yLinearManipulator->SetLocalOrientation(manipulatorOrientation);
m_zLinearManipulator->SetLocalOrientation(manipulatorOrientation);
m_yLinearManipulator->SetAxis(action.m_current.m_delta.TransformVector(AZ::Vector3::CreateAxisY()));
m_zLinearManipulator->SetAxis(action.m_current.m_delta.TransformVector(AZ::Vector3::CreateAxisZ()));
m_xRotationManipulator->SetLocalOrientation(manipulatorOrientation);
m_yLinearManipulator->SetBoundsDirty();
m_zLinearManipulator->SetBoundsDirty();
m_xRotationManipulator->SetBoundsDirty();
});
m_xRotationManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_yLinearManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_zLinearManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_yzPlanarManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityComponentId.GetEntityId());
Refresh();
}
EditorSubComponentModeAngleCone::~EditorSubComponentModeAngleCone()
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_xRotationManipulator->Unregister();
m_yLinearManipulator->Unregister();
m_zLinearManipulator->Unregister();
m_yzPlanarManipulator->Unregister();
}
void EditorSubComponentModeAngleCone::Refresh()
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
float coneHeight = ConeHeight;
AngleLimitsFloatPair yzSwingAngleLimits;
EditorJointRequestBus::EventResult(
yzSwingAngleLimits, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
// Draw inverted cone (negative cone height) if angles are larger than 90 deg.
if (yzSwingAngleLimits.first > 90.0f || yzSwingAngleLimits.second > 90.0f)
{
coneHeight = -ConeHeight;
}
// reposition manipulators
const AZ::Quaternion localRotation = localTransform.GetRotation();
const AZ::Vector3 linearManipulatorOffset = localTransform.GetTranslation() + localRotation.TransformVector(AZ::Vector3(coneHeight, 0.0f, 0.0f));
m_xRotationManipulator->SetLocalTransform(localTransform);
m_xRotationManipulator->SetBoundsDirty();
localTransform.SetTranslation(linearManipulatorOffset);
m_yLinearManipulator->SetLocalTransform(localTransform);
m_zLinearManipulator->SetLocalTransform(localTransform);
m_yzPlanarManipulator->SetLocalTransform(localTransform);
m_yLinearManipulator->SetBoundsDirty();
m_zLinearManipulator->SetBoundsDirty();
m_yzPlanarManipulator->SetBoundsDirty();
}
void EditorSubComponentModeAngleCone::ConfigureLinearView(
float axisLength, [[maybe_unused]] const AZ::Color& axis1Color, const AZ::Color& axis2Color,
const AZ::Color& axis3Color)
{
const float coneLength = 0.28f;
const float coneRadius = 0.07f;
const auto configureLinearView = [coneLength, axisLength, coneRadius](
AzToolsFramework::LinearManipulator* linearManipulator, const AZ::Color& color)
{
AzToolsFramework::ManipulatorViews views;
views.emplace_back(CreateManipulatorViewLine(
*linearManipulator, color, axisLength, AzToolsFramework::ManipulatorLineBoundWidth()));
views.emplace_back(CreateManipulatorViewCone(
*linearManipulator, color, linearManipulator->GetAxis() * (axisLength - coneLength),
coneLength, coneRadius));
linearManipulator->SetViews(AZStd::move(views));
};
configureLinearView(m_yLinearManipulator.get(), axis2Color);
configureLinearView(m_zLinearManipulator.get(), axis3Color);
}
void EditorSubComponentModeAngleCone::ConfigurePlanarView(const AZ::Color& planeColor,
const AZ::Color& plane2Color)
{
const float planeSize = 0.6f;
AzToolsFramework::ManipulatorViews views;
views.emplace_back(CreateManipulatorViewQuad(
*m_yzPlanarManipulator
, planeColor
, plane2Color
, planeSize));
m_yzPlanarManipulator->SetViews(AZStd::move(views));
}
void EditorSubComponentModeAngleCone::DisplayEntityViewport(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
AZ::u32 stateBefore = debugDisplay.GetState();
debugDisplay.CullOff();
debugDisplay.PushMatrix(worldTransform);
debugDisplay.PushMatrix(localTransform);
const float xAxisArrowLength = 2.0f;
debugDisplay.SetColor(AZ::Color(1.0f, 0.0f, 0.0f, 1.0f));
debugDisplay.DrawArrow(AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3(xAxisArrowLength, 0.0f, 0.0f));
AngleLimitsFloatPair yzSwingAngleLimits;
EditorJointRequestBus::EventResult(
yzSwingAngleLimits, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
const AZ::u32 numEllipseSamples = 16;
AZ::Vector3 ellipseSamples[numEllipseSamples];
float coneHeight = ConeHeight;
// Draw inverted cone if angles are larger than 90 deg.
if (yzSwingAngleLimits.first > 90.0f || yzSwingAngleLimits.second > 90.0f)
{
coneHeight = -ConeHeight;
}
// Compute points along perimeter of cone base
const float coney = tanf(AZ::DegToRad(yzSwingAngleLimits.first)) * coneHeight;
const float conez = tanf(AZ::DegToRad(yzSwingAngleLimits.second)) * coneHeight;
const float step = AZ::Constants::TwoPi / numEllipseSamples;
for (size_t i = 0; i < numEllipseSamples; ++i)
{
const float angleStep = step * i;
ellipseSamples[i].SetX(coneHeight);
ellipseSamples[i].SetY(conez * sin(angleStep));
ellipseSamples[i].SetZ(coney * cos(angleStep));
}
// draw cone
for (size_t i = 0; i < numEllipseSamples; ++i)
{
size_t nextIndex = i + 1;
if (i == numEllipseSamples - 1)
{
nextIndex = 0;
}
// draw cone sides
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, 0.2f));
debugDisplay.DrawTri(AZ::Vector3(0.0f, 0.0f, 0.0f), ellipseSamples[i], ellipseSamples[nextIndex]);
// draw parameter of cone base
debugDisplay.SetColor(AZ::Color(0.4f, 0.4f, 0.4f, 0.4f));
debugDisplay.DrawLine(ellipseSamples[i], ellipseSamples[nextIndex]);
}
// draw axis lines at base of cone, and from tip to base.
debugDisplay.SetColor(AZ::Color(0.5f, 0.5f, 0.5f, 0.6f));
debugDisplay.DrawLine(ellipseSamples[0], ellipseSamples[numEllipseSamples/2]);
debugDisplay.DrawLine(ellipseSamples[numEllipseSamples*3/4], ellipseSamples[numEllipseSamples/4]);
debugDisplay.DrawLine(AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3(coneHeight, 0.0f, 0.0f));
debugDisplay.PopMatrix();//pop local transform
debugDisplay.PopMatrix();//pop world transform
debugDisplay.SetState(stateBefore);
// reposition and reorientate manipulators
Refresh();
}
} // namespace PhysX
@@ -1,63 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Editor/EditorSubComponentModeBase.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
namespace AzToolsFramework
{
class AngularManipulator;
class LinearManipulator;
class PlanarManipulator;
}
namespace PhysX
{
class EditorSubComponentModeAngleCone
: public PhysX::EditorSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
EditorSubComponentModeAngleCone(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, float max
, float min);
~EditorSubComponentModeAngleCone();
// PhysX::EditorSubComponentModeBase
void Refresh() override;
private:
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
void ConfigureLinearView(
float axisLength,
const AZ::Color& axis1Color, const AZ::Color& axis2Color,
const AZ::Color& axis3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
void ConfigurePlanarView(const AZ::Color& planeColor = AZ::Color(0.0f, 1.0f, 0.0f, 0.5f)
, const AZ::Color& plane2Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
AZStd::shared_ptr<AzToolsFramework::AngularManipulator> m_xRotationManipulator;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_yLinearManipulator;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_zLinearManipulator;
AZStd::shared_ptr<AzToolsFramework::PlanarManipulator> m_yzPlanarManipulator;
float m_max = FLT_MAX;
float m_min = 0.0f;
};
} // namespace PhysX
@@ -1,318 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Component/TransformBus.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/EditorSubComponentModeAnglePair.h>
#include <Source/Utils.h>
namespace
{
const float Alpha = 0.6f;
const AZ::Color ColorDefault = AZ::Color(1.0f, 1.0f, 1.0f, Alpha);
const AZ::Color ColorFirst = AZ::Color(1.0f, 0.0f, 0.0f, Alpha);
const AZ::Color ColorSecond = AZ::Color(0.0f, 1.0f, 0.0f, Alpha);
const AZ::Color ColorSweepArc = AZ::Color(1.0f, 1.0f, 1.0f, Alpha);
const float SweepLineDisplaceFactor = 0.5f;
const float SweepLineThickness = 1.0f;
const float SweepLineGranularity = 1.0f;
}
namespace PhysX
{
EditorSubComponentModeAnglePair::EditorSubComponentModeAnglePair(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, const AZ::Vector3& axis
, float firstMax
, float firstMin
, float secondMax
, float secondMin)
: EditorSubComponentModeBase(entityComponentIdPair, componentType, name)
, m_axis(axis)
, m_firstMax(firstMax)
, m_firstMin(firstMin)
, m_secondMax(secondMax)
, m_secondMin(secondMin)
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
AZ::Vector3 displacement = m_axis;
AZ::Transform displacementTransform = localTransform;
AZ::Vector3 displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_firstManipulator = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_firstManipulator->AddEntityComponentIdPair(m_entityComponentId);
m_firstManipulator->SetAxis(m_axis);
m_firstManipulator->SetLocalTransform(displacementTransform);
displacement = -m_axis;
displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_secondManipulator = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_secondManipulator->AddEntityComponentIdPair(m_entityComponentId);
m_secondManipulator->SetAxis(m_axis);
m_secondManipulator->SetLocalTransform(displacementTransform);
const float manipulatorRadius = 2.0f;
const float manipulatorWidth = 0.05f;
m_firstManipulator->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_firstManipulator, ColorFirst,
manipulatorRadius, manipulatorWidth, AzToolsFramework::DrawHalfDottedCircle));
m_secondManipulator->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_secondManipulator, ColorSecond,
manipulatorRadius, manipulatorWidth, AzToolsFramework::DrawHalfDottedCircle));
Refresh();
AZStd::shared_ptr<SharedRotationState> sharedRotationState =
AZStd::make_shared<SharedRotationState>();
auto mouseDownCallback = [this, sharedRotationState](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
const AZ::Quaternion normalizedStart = action.m_start.m_rotation.GetNormalized();
sharedRotationState->m_axis = AZ::Vector3(normalizedStart.GetX(), normalizedStart.GetY(), normalizedStart.GetZ());
sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity();
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
sharedRotationState->m_valuePair = currentValue;
};
m_firstManipulator->InstallLeftMouseDownCallback(mouseDownCallback);
m_secondManipulator->InstallLeftMouseDownCallback(mouseDownCallback);
m_firstManipulator->InstallMouseMoveCallback(
[this, sharedRotationState]
(const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
float angleDelta;
AZ::Quaternion manipulatorOrientation;
const float newValue = MouseMove(sharedRotationState, action, true, angleDelta, manipulatorOrientation);
if (newValue > m_firstMax || newValue < m_firstMin)
{
return;
}
m_firstManipulator->SetLocalOrientation(manipulatorOrientation);
const float newFirstValue = AZ::GetClamp(sharedRotationState->m_valuePair.first + angleDelta, m_firstMin, m_firstMax);
EditorJointRequestBus::Event(
m_entityComponentId
, &EditorJointRequests::SetLinearValuePair
, m_name
, AngleLimitsFloatPair(newFirstValue, sharedRotationState->m_valuePair.second));
m_firstManipulator->SetBoundsDirty();
});
m_secondManipulator->InstallMouseMoveCallback(
[this, sharedRotationState]
(const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
float angleDelta;
AZ::Quaternion manipulatorOrientation;
const float newValue = MouseMove(sharedRotationState, action, false, angleDelta, manipulatorOrientation);
if (newValue > m_secondMax || newValue < m_secondMin)
{
return; //Not handling values exceeding limits
}
m_secondManipulator->SetLocalOrientation(manipulatorOrientation);
float newSecondValue = AZ::GetClamp(sharedRotationState->m_valuePair.second + angleDelta, m_secondMin, m_secondMax);
EditorJointRequestBus::Event(
m_entityComponentId
, &EditorJointRequests::SetLinearValuePair
, m_name
, AngleLimitsFloatPair(sharedRotationState->m_valuePair.first, newSecondValue));
m_secondManipulator->SetBoundsDirty();
});
m_firstManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_secondManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityComponentId.GetEntityId());
}
EditorSubComponentModeAnglePair::~EditorSubComponentModeAnglePair()
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_firstManipulator->Unregister();
m_secondManipulator->Unregister();
}
void EditorSubComponentModeAnglePair::Refresh()
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
AZ::Transform displacementTransform = localTransform;
AZ::Vector3 displacement = m_axis;
AZ::Vector3 displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_firstManipulator->SetLocalTransform(displacementTransform);
displacement = -m_axis;
displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_secondManipulator->SetLocalTransform(displacementTransform);
m_firstManipulator->SetBoundsDirty();
m_secondManipulator->SetBoundsDirty();
}
void EditorSubComponentModeAnglePair::DisplayEntityViewport(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, m_name);
const float size = 2.0f;
AZ::Vector3 axisPoint = m_axis * size * 0.5f;
AZStd::array<AZ::Vector3, 4> points = {
-axisPoint
, axisPoint
, axisPoint
, -axisPoint
};
if (abs(m_axis.GetX() - 1.0f) < FLT_EPSILON)
{
points[2].SetZ(size);
points[3].SetZ(size);
}
else if (abs(m_axis.GetY() - 1.0f) < FLT_EPSILON)
{
points[2].SetX(size);
points[3].SetX(size);
}
else if (abs(m_axis.GetZ() - 1.0f) < FLT_EPSILON)
{
points[2].SetX(size);
points[3].SetX(size);
}
AZ::u32 stateBefore = debugDisplay.GetState();
debugDisplay.CullOff();
debugDisplay.SetAlpha(Alpha);
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
debugDisplay.PushMatrix(worldTransform);
debugDisplay.PushMatrix(localTransform);
debugDisplay.SetColor(ColorSweepArc);
const AZ::Vector3 zeroVector = AZ::Vector3::CreateZero();
const AZ::Vector3 posPosition = m_axis * SweepLineDisplaceFactor;
const AZ::Vector3 negPosition = -posPosition;
debugDisplay.DrawArc(posPosition, SweepLineThickness, -currentValue.first, currentValue.first, SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(zeroVector, SweepLineThickness, -currentValue.first, currentValue.first, SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(negPosition, SweepLineThickness, -currentValue.first, currentValue.first, SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(posPosition, SweepLineThickness, 0.0f, abs(currentValue.second), SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(zeroVector, SweepLineThickness, 0.0f, abs(currentValue.second), SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(negPosition, SweepLineThickness, 0.0f, abs(currentValue.second), SweepLineGranularity, -m_axis);
AZ::Quaternion firstRotate = AZ::Quaternion::CreateFromAxisAngle(m_axis, AZ::DegToRad(currentValue.first));
AZ::Transform firstTM = AZ::Transform::CreateFromQuaternion(firstRotate);
debugDisplay.PushMatrix(firstTM);
debugDisplay.SetColor(ColorFirst);
debugDisplay.DrawQuad(points[0], points[1], points[2], points[3]);
debugDisplay.PopMatrix();
AZ::Quaternion secondRotate = AZ::Quaternion::CreateFromAxisAngle(m_axis, AZ::DegToRad(currentValue.second));
AZ::Transform secondTM = AZ::Transform::CreateFromQuaternion(secondRotate);
debugDisplay.PushMatrix(secondTM);
debugDisplay.SetColor(ColorSecond);
debugDisplay.DrawQuad(points[0], points[1], points[2], points[3]);
debugDisplay.PopMatrix();
debugDisplay.SetColor(ColorDefault);
debugDisplay.DrawQuad(points[0], points[1], points[2], points[3]);
debugDisplay.PopMatrix(); // pop local transform
debugDisplay.PopMatrix(); // pop global transform
debugDisplay.SetState(stateBefore);
// reposition and reorientate manipulators
Refresh();
}
float EditorSubComponentModeAnglePair::MouseMove(AZStd::shared_ptr<SharedRotationState>& sharedRotationState
, const AzToolsFramework::AngularManipulator::Action& action
, bool isFirstValue
, float& angleDelta
, AZ::Quaternion& manipulatorOrientation)
{
sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull();
angleDelta = 0.0f;
AZ::Vector3 axis = m_axis;
sharedRotationState->m_savedOrientation.ConvertToAxisAngle(axis, angleDelta);
// Polarity of axis is switched by ConvertToAxisAngle call depending on direction of rotation
if (abs(m_axis.GetX() - 1.0f) < FLT_EPSILON)
{
angleDelta = AZ::RadToDeg(angleDelta) * axis.GetX();
}
else if (abs(m_axis.GetY() - 1.0f) < FLT_EPSILON)
{
angleDelta = AZ::RadToDeg(angleDelta) * axis.GetY();
}
else if (abs(m_axis.GetZ() - 1.0f) < FLT_EPSILON)
{
angleDelta = AZ::RadToDeg(angleDelta) * axis.GetZ();
}
manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
if (isFirstValue)
{
return sharedRotationState->m_valuePair.first + angleDelta;
}
else
{
return sharedRotationState->m_valuePair.second + angleDelta;
}
}
} // namespace PhysX
@@ -1,66 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Editor/EditorSubComponentModeBase.h>
#include <PhysX/EditorJointBus.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
namespace PhysX
{
class EditorSubComponentModeAnglePair
: public PhysX::EditorSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
EditorSubComponentModeAnglePair(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, const AZ::Vector3& axis
, float firstMax
, float firstMin
, float secondMax
, float secondMin);
~EditorSubComponentModeAnglePair();
// PhysX::EditorSubComponentModeBase
void Refresh() override;
private:
struct SharedRotationState
{
AZ::Vector3 m_axis;
AZ::Quaternion m_savedOrientation = AZ::Quaternion::CreateIdentity();
AngleLimitsFloatPair m_valuePair;
};
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
float MouseMove(AZStd::shared_ptr<SharedRotationState>& sharedRotationState
, const AzToolsFramework::AngularManipulator::Action& action
, bool isFirstValue
, float& angleDelta
, AZ::Quaternion& manipulatorOrientation);
AZStd::shared_ptr<AzToolsFramework::AngularManipulator> m_firstManipulator;
AZStd::shared_ptr<AzToolsFramework::AngularManipulator> m_secondManipulator;
AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX();
float m_firstMax = FLT_MAX;
float m_firstMin = -FLT_MAX;
float m_secondMax = FLT_MAX;
float m_secondMin = -FLT_MAX;
};
} // namespace PhysX
@@ -1,37 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <Editor/EditorJointTypeDrawer.h>
#include <Editor/EditorSubComponentModeBase.h>
#include <AzCore/std/smart_ptr/make_shared.h>
namespace PhysX
{
EditorSubComponentModeBase::EditorSubComponentModeBase(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name)
: m_entityComponentId(entityComponentIdPair),
m_name(name)
{
// The first time this is called, no object will respond to this bus call as no object is connected at the address,
// and m_jointTypeDrawer will remain as a nullptr.
EditorJointTypeDrawerBus::EventResult(m_jointTypeDrawer,
EditorJointTypeDrawerId(componentType, EditorSubComponentModeNameCrc(name)),
&EditorJointTypeDrawerBus::Events::GetEditorJointTypeDrawer);
if (!m_jointTypeDrawer)
{
// Once this is called, the bus call to GetEditorJointTypeDrawer above will no longer get a null response, until m_jointTypeDrawer is destroyed.
m_jointTypeDrawer = AZStd::make_shared<EditorJointTypeDrawer>(componentType,
AzToolsFramework::GetEntityContextId(),
m_name);
}
}
} // namespace PhysX
@@ -1,55 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/ComponentBus.h>
namespace AzFramework
{
class DebugDisplayRequests;
struct ViewportInfo;
}
namespace AzToolsFramework
{
namespace ViewportInteraction
{
struct MouseInteractionEvent;
}
}
namespace PhysX
{
class EditorJointTypeDrawer;
/// Base class for (joints) sub-component modes.
class EditorSubComponentModeBase
{
public:
EditorSubComponentModeBase(
const AZ::EntityComponentIdPair& entityComponentIdPair,
const AZ::Uuid& componentType,
const AZStd::string& name);
virtual ~EditorSubComponentModeBase() = default;
/// Additional mouse handling by sub-component mode. Does not absorb mouse event.
virtual void HandleMouseInteraction(
[[maybe_unused]] const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) {};
virtual void Refresh() = 0;
AZStd::string m_name;///< Name of sub-component mode.
protected:
AZ::EntityComponentIdPair m_entityComponentId;///< Entity Id and component pair.
private:
AZStd::shared_ptr<EditorJointTypeDrawer> m_jointTypeDrawer;///< Drawer that draws component type specific objects in the viewport.
};
} // namespace PhysX
@@ -1,133 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Component/TransformBus.h>
#include <AzCore/std/smart_ptr/intrusive_ptr.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/EditorSubComponentModeLinear.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
EditorSubComponentModeLinear::EditorSubComponentModeLinear(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, float exponent
, float max
, float min)
: EditorSubComponentModeBase(entityComponentIdPair, componentType, name)
, m_exponent(exponent)
, m_inverseExponent(1.0f/exponent)
, m_max(max)
, m_min(min)
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
m_manipulator = AzToolsFramework::LinearManipulator::MakeShared(worldTransform);
m_manipulator->AddEntityComponentIdPair(m_entityComponentId);
m_manipulator->SetAxis(AZ::Vector3::CreateAxisX());
m_manipulator->SetLocalTransform(localTransform);
Refresh();
const AZ::Color manipulatorColor(0.3f, 0.3f, 0.3f, 1.0f);
const float manipulatorSize = 0.05f;
AzToolsFramework::ManipulatorViews views;
views.emplace_back(AzToolsFramework::CreateManipulatorViewQuadBillboard(manipulatorColor
, manipulatorSize));
m_manipulator->SetViews(AZStd::move(views));
struct SharedState
{
float m_startingValue = 0.0f;
};
auto sharedState = AZStd::make_shared<SharedState>();
m_manipulator->InstallLeftMouseDownCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& /*action*/) mutable
{
float currentValue = 0.0f;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValue
, m_name);
sharedState->m_startingValue = currentValue;
});
m_manipulator->InstallMouseMoveCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& action)
{
const float axisDisplacement = action.LocalPositionOffset().Dot(action.m_fixed.m_axis);
float newValue = AZ::GetClamp(sharedState->m_startingValue + DisplacementToDeltaValue(axisDisplacement), m_min, m_max);
EditorJointRequestBus::Event(
m_entityComponentId
, &EditorJointRequests::SetLinearValue
, m_name
, newValue);
const AZ::Vector3 localPosition = action.LocalPosition().GetMax(AZ::Vector3(0.01f, 0.0f, 0.0f));
m_manipulator->SetLocalTransform(AZ::Transform::CreateTranslation(localPosition));
m_manipulator->SetBoundsDirty();
});
m_manipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
}
EditorSubComponentModeLinear::~EditorSubComponentModeLinear()
{
m_manipulator->Unregister();
}
void EditorSubComponentModeLinear::Refresh()
{
float currentValue = 0.0f;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentId
, &EditorJointRequests::GetLinearValue
, m_name);
m_manipulator->SetLocalTransform(AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisX() * ValueToDisplacement(currentValue)));
}
float EditorSubComponentModeLinear::DisplacementToDeltaValue(float displacement) const
{
if (displacement > 0.0f)
{
return powf(displacement, m_exponent);
}
else if (displacement < 0.0f)
{
return -powf(fabsf(displacement), m_exponent);
}
else
{
return 0.0f;
}
}
float EditorSubComponentModeLinear::ValueToDisplacement(float value) const
{
return powf(value, m_inverseExponent);
}
} // namespace PhysX
@@ -1,46 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Editor/EditorSubComponentModeBase.h>
namespace AzToolsFramework
{
class LinearManipulator;
}
namespace PhysX
{
class EditorSubComponentModeLinear
: public PhysX::EditorSubComponentModeBase
{
public:
EditorSubComponentModeLinear(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, float exponent
, float max
, float min);
~EditorSubComponentModeLinear();
// PhysX::EditorSubComponentModeBase
void Refresh() override;
private:
float DisplacementToDeltaValue(float displacement) const;
float ValueToDisplacement(float value) const;
float m_exponent = 1.0f;
float m_inverseExponent = 1.0f;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_manipulator;
float m_max = FLT_MAX;
float m_min = -FLT_MAX;
};
} // namespace PhysX
@@ -1,151 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Component/TransformBus.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <Editor/EditorJointComponentMode.h>
#include <PhysX/EditorJointBus.h>
#include <Editor/EditorSubComponentModeRotation.h>
#include <Source/Utils.h>
namespace PhysX
{
EditorSubComponentModeRotation::EditorSubComponentModeRotation(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name)
: EditorSubComponentModeBase(entityComponentIdPair, componentType, name)
{
CreateManipulators();
RegisterManipulators();
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityComponentId.GetEntityId());
}
EditorSubComponentModeRotation::~EditorSubComponentModeRotation()
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
UnregisterManipulators();
}
void EditorSubComponentModeRotation::Refresh()
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
for (auto rotationManipulator : m_rotationManipulators)
{
rotationManipulator->SetLocalTransform(localTransform);
rotationManipulator->SetBoundsDirty();
}
}
void EditorSubComponentModeRotation::DisplayEntityViewport(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
[[maybe_unused]] AzFramework::DebugDisplayRequests& debugDisplay)
{
Refresh(); //Update position and orientation of manipulators.
}
void EditorSubComponentModeRotation::CreateManipulators()
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
const AZ::Quaternion worldRotation = worldTransform.GetRotation();
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
const AZStd::array<AZ::Vector3, 3> axes = { AZ::Vector3::CreateAxisX()
, AZ::Vector3::CreateAxisY()
, AZ::Vector3::CreateAxisZ()};
const AZStd::array <AZ::Color, 3> colors = { AZ::Color(1.0f, 0.0f, 0.0f, 1.0f)
, AZ::Color(0.0f, 1.0f, 0.0f, 1.0f)
, AZ::Color(0.0f, 0.0f, 1.0f, 1.0f)};
for (AZ::u32 i = 0; i < 3; ++i)
{
m_rotationManipulators[i] = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_rotationManipulators[i]->AddEntityComponentIdPair(m_entityComponentId);
m_rotationManipulators[i]->SetAxis(axes[i]);
m_rotationManipulators[i]->SetLocalTransform(localTransform);
const float manipulatorRadius = 2.0f;
m_rotationManipulators[i]->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_rotationManipulators[i], colors[i], manipulatorRadius,
AzToolsFramework::ManipulatorCicleBoundWidth(), AzToolsFramework::DrawHalfDottedCircle));
}
Refresh();
InstallManipulatorMouseCallbacks();
}
void EditorSubComponentModeRotation::InstallManipulatorMouseCallbacks()
{
struct SharedState
{
AZ::Transform m_startTM;
};
auto sharedState = AZStd::make_shared<SharedState>();
auto mouseDownRotateXCallback = [this, sharedState]([[maybe_unused]] const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
PhysX::EditorJointRequestBus::EventResult(sharedState->m_startTM
, m_entityComponentId
, &PhysX::EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
};
for (AZ::u32 index = 0; index < 3; ++index)
{
m_rotationManipulators[index]->InstallLeftMouseDownCallback(mouseDownRotateXCallback);
m_rotationManipulators[index]->InstallMouseMoveCallback(
[this, index, sharedState]
(const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
AZ::Transform newTransform = AZ::Transform::CreateIdentity();
newTransform = sharedState->m_startTM * AZ::Transform::CreateFromQuaternion(action.m_current.m_delta);
PhysX::EditorJointRequestBus::Event(m_entityComponentId
, &PhysX::EditorJointRequests::SetVector3Value
, PhysX::EditorJointComponentMode::s_parameterRotation
, newTransform.GetRotation().GetEulerDegrees());
m_rotationManipulators[index]->SetLocalOrientation(manipulatorOrientation);
m_rotationManipulators[index]->SetBoundsDirty();
});
}
}
void EditorSubComponentModeRotation::RegisterManipulators()
{
for (auto rotationManipulator : m_rotationManipulators)
{
rotationManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
}
}
void EditorSubComponentModeRotation::UnregisterManipulators()
{
for (auto rotationManipulator : m_rotationManipulators)
{
rotationManipulator->Unregister();
}
}
}
@@ -1,48 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Editor/EditorSubComponentModeBase.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
namespace AzToolsFramework
{
class AngularManipulator;
}
namespace PhysX
{
class EditorSubComponentModeRotation
: public PhysX::EditorSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
EditorSubComponentModeRotation(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name);
~EditorSubComponentModeRotation();
// PhysX::EditorSubComponentModeBase
void Refresh() override;
private:
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
void CreateManipulators();
void InstallManipulatorMouseCallbacks();
void RegisterManipulators();
void UnregisterManipulators();
AZStd::array<AZStd::shared_ptr<AzToolsFramework::AngularManipulator>, 3> m_rotationManipulators;
};
} // namespace PhysX
@@ -1,97 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/Color.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/EditorSubComponentModeSnapPosition.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
EditorSubComponentModeSnapPosition::EditorSubComponentModeSnapPosition(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, bool selectLeadOnSnap)
: EditorSubComponentModeSnap(entityComponentIdPair, componentType, name)
, m_selectLeadOnSnap(selectLeadOnSnap)
{
InitMouseDownCallBack();
m_manipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityComponentId.GetEntityId());
}
EditorSubComponentModeSnapPosition::~EditorSubComponentModeSnapPosition()
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_manipulator->Unregister();
}
void EditorSubComponentModeSnapPosition::DisplaySpecificSnapType(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
const float snapLength)
{
const float arrowLength = 1.0f;
const float iconGap = 1.0f;
const AZ::Vector3 iconPosition = jointPosition +
(snapDirection * (snapLength + arrowLength + iconGap));
debugDisplay.SetColor(AZ::Colors::Red);
debugDisplay.DrawArrow(iconPosition, iconPosition + AZ::Vector3(arrowLength, 0.0f, 0.0f));
debugDisplay.SetColor(AZ::Colors::Green);
debugDisplay.DrawArrow(iconPosition, iconPosition + AZ::Vector3(0.2f, arrowLength, 0.2f));
debugDisplay.SetColor(AZ::Colors::Blue);
debugDisplay.DrawArrow(iconPosition, iconPosition + AZ::Vector3(0.0f, 0.0f, arrowLength));
}
void EditorSubComponentModeSnapPosition::InitMouseDownCallBack()
{
m_manipulator->InstallLeftMouseDownCallback(
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/) mutable
{
if (!m_pickedEntity.IsValid())
{
return;
}
const AZ::Vector3 newLocalPosition = PhysX::Utils::ComputeJointLocalTransform(
PhysX::Utils::GetEntityWorldTransformWithScale(m_pickedEntity),
PhysX::Utils::GetEntityWorldTransformWithScale(m_entityComponentId.GetEntityId())).GetTranslation();
PhysX::EditorJointRequestBus::Event(m_entityComponentId
, &PhysX::EditorJointRequests::SetVector3Value
, PhysX::EditorJointComponentMode::s_parameterPosition
, newLocalPosition);
const bool selectedEntityIsNotJointEntity = m_pickedEntity != m_entityComponentId.GetEntityId();
AZ_Error("EditorSubComponentModeSnapPosition",
selectedEntityIsNotJointEntity,
"Joint's lead entity cannot be the same as the entity in which the joint resides. Select lead entity on snap failed.");
if (m_selectLeadOnSnap &&
selectedEntityIsNotJointEntity)
{
PhysX::EditorJointRequestBus::Event(m_entityComponentId
, &PhysX::EditorJointRequests::SetEntityIdValue
, PhysX::EditorJointComponentMode::s_parameterLeadEntity
, m_pickedEntity);
}
m_manipulator->SetBoundsDirty();
});
}
} // namespace PhysX
@@ -1,42 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Editor/EditorSubComponentModeSnap.h>
namespace PhysX
{
/// This sub-component mode gets an entity position from its base class on mouse down
/// and sets a position (AZ::Vector3) value in the component that uses it.
class EditorSubComponentModeSnapPosition
: public EditorSubComponentModeSnap
{
public:
EditorSubComponentModeSnapPosition(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name
, bool selectLeadOnSnap);
~EditorSubComponentModeSnapPosition() override;
protected:
// PhysX::EditorSubComponentModeSnap
void DisplaySpecificSnapType(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
float snapLength) override;
void InitMouseDownCallBack() override;
private:
bool m_selectLeadOnSnap = true;
};
} // namespace PhysX
@@ -1,122 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/EditorJointComponentMode.h>
#include <Editor/EditorSubComponentModeSnapRotation.h>
#include <PhysX/EditorJointBus.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/Color.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
namespace PhysX
{
EditorSubComponentModeSnapRotation::EditorSubComponentModeSnapRotation(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name)
: EditorSubComponentModeSnap(entityComponentIdPair, componentType, name)
{
InitMouseDownCallBack();
m_manipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityComponentId.GetEntityId());
}
EditorSubComponentModeSnapRotation::~EditorSubComponentModeSnapRotation()
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_manipulator->Unregister();
}
void EditorSubComponentModeSnapRotation::DisplaySpecificSnapType(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
const float snapLength)
{
const float circleRadius = 0.5f;
const float iconGap = 1.0f;
const AZ::Vector3 iconPosition = jointPosition +
(snapDirection * (snapLength + circleRadius * 2.0f + iconGap));
debugDisplay.SetColor(AZ::Colors::Red);
debugDisplay.DrawCircle(iconPosition, circleRadius, 0);
debugDisplay.SetColor(AZ::Colors::Green);
debugDisplay.DrawCircle(iconPosition, circleRadius, 1);
debugDisplay.SetColor(AZ::Colors::Blue);
debugDisplay.DrawCircle(iconPosition, circleRadius, 2);
}
void EditorSubComponentModeSnapRotation::InitMouseDownCallBack()
{
m_manipulator->InstallLeftMouseDownCallback(
[this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action) mutable
{
if (!m_pickedEntity.IsValid())
{
return;
}
AZ::EntityId leadEntityId;
PhysX::EditorJointRequestBus::EventResult(leadEntityId,
m_entityComponentId,
&PhysX::EditorJointRequests::GetEntityIdValue,
PhysX::EditorJointComponentMode::s_parameterLeadEntity);
if (leadEntityId.IsValid() && m_pickedEntity == leadEntityId)
{
AZ_Warning("EditorsubComponentModeSnapRotation",
false,
"The entity %s is the lead of the joint. Please snap rotation (or orientation) of joint to another entity that is not the lead entity.",
GetPickedEntityName().c_str());
return;
}
AZ::Transform worldTransform = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(
worldTransform, m_entityComponentId.GetEntityId(), &AZ::TransformInterface::GetWorldTM);
worldTransform.ExtractUniformScale();
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
AZ::Transform pickedEntityTransform = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(
pickedEntityTransform, m_pickedEntity, &AZ::TransformInterface::GetWorldTM);
const AZ::Transform worldTransformInv = worldTransform.GetInverse();
const AZ::Vector3 pickedLocalPosition = worldTransformInv.TransformVector(pickedEntityTransform.GetTranslation()) - localTransform.GetTranslation();
if (abs(pickedLocalPosition.GetLength()) < FLT_EPSILON)
{
AZ_Warning("EditorsubComponentModeSnapRotation",
false,
"The entity %s is too close to the joint position. Please snap rotation to an entity that is not at the position of the joint.",
GetPickedEntityName().c_str());
return;
}
const AZ::Vector3 targetDirection = pickedLocalPosition.GetNormalized();
const AZ::Vector3 sourceDirection = AZ::Vector3::CreateAxisX();
const AZ::Quaternion newLocalRotation = AZ::Quaternion::CreateShortestArc(sourceDirection, targetDirection);
PhysX::EditorJointRequestBus::Event(m_entityComponentId
, &PhysX::EditorJointRequests::SetVector3Value
, PhysX::EditorJointComponentMode::s_parameterRotation //using rotation parameter name to set the local rotation value
, newLocalRotation.GetEulerDegrees());
m_manipulator->SetBoundsDirty();
});
}
} // namespace PhysX
@@ -1,38 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Editor/EditorSubComponentModeSnap.h>
namespace PhysX
{
/// TThis sub-component mode gets an entity position from its base class on mouse down
/// and sets a rotation (AZ::Quaternion) value in the component that uses it.
class EditorSubComponentModeSnapRotation
: public EditorSubComponentModeSnap
{
public:
EditorSubComponentModeSnapRotation(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name);
~EditorSubComponentModeSnapRotation() override;
protected:
// PhysX::EditorSubComponentModeSnap
void DisplaySpecificSnapType(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
float snapLength) override;
void InitMouseDownCallBack() override;
};
} // namespace PhysX
@@ -1,91 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Component/TransformBus.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <Editor/EditorSubComponentModeVec3.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
EditorSubComponentModeVec3::EditorSubComponentModeVec3(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name)
: EditorSubComponentModeBase(entityComponentIdPair, componentType, name)
, m_translationManipulators(AzToolsFramework::TranslationManipulators::Dimensions::Three,
AZ::Transform::Identity(), AZ::Vector3::CreateOne())
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Vector3 localTranslation;
EditorJointRequestBus::EventResult(
localTranslation, m_entityComponentId
, &EditorJointRequests::GetVector3Value
, m_name);
m_translationManipulators.SetSpace(worldTransform);
m_translationManipulators.SetLocalPosition(localTranslation);
m_translationManipulators.AddEntityComponentIdPair(m_entityComponentId);
m_translationManipulators.Register(AzToolsFramework::g_mainManipulatorManagerId);
AzToolsFramework::ConfigureTranslationManipulatorAppearance3d(&m_translationManipulators);
m_translationManipulators.InstallLinearManipulatorMouseMoveCallback([this](
const AzToolsFramework::LinearManipulator::Action& action)
{
OnManipulatorMoved(action.LocalPosition());
});
m_translationManipulators.InstallPlanarManipulatorMouseMoveCallback([this](
const AzToolsFramework::PlanarManipulator::Action& action)
{
OnManipulatorMoved(action.LocalPosition());
});
m_translationManipulators.InstallSurfaceManipulatorMouseMoveCallback([this](
const AzToolsFramework::SurfaceManipulator::Action& action)
{
OnManipulatorMoved(action.LocalPosition());
});
}
EditorSubComponentModeVec3::~EditorSubComponentModeVec3()
{
m_translationManipulators.Unregister();
}
void EditorSubComponentModeVec3::Refresh()
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Vector3 localTranslation;
EditorJointRequestBus::EventResult(
localTranslation, m_entityComponentId
, &EditorJointRequests::GetVector3Value
, m_name);
m_translationManipulators.SetSpace(worldTransform);
m_translationManipulators.SetLocalPosition(localTranslation);
m_translationManipulators.SetBoundsDirty();
}
void EditorSubComponentModeVec3::OnManipulatorMoved(const AZ::Vector3& position)
{
m_translationManipulators.SetLocalPosition(position);
EditorJointRequestBus::Event(
m_entityComponentId
, &EditorJointRequests::SetVector3Value
, m_name
, position);
}
} // namespace PhysX
@@ -1,34 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
#include <Editor/EditorSubComponentModeBase.h>
namespace PhysX
{
class EditorSubComponentModeVec3
: public PhysX::EditorSubComponentModeBase
{
public:
EditorSubComponentModeVec3(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name);
~EditorSubComponentModeVec3();
// PhysX::EditorSubComponentModeBase
void Refresh() override;
private:
void OnManipulatorMoved(const AZ::Vector3& position);
AzToolsFramework::TranslationManipulators m_translationManipulators;
};
} // namespace PhysX
@@ -0,0 +1,601 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsComponentMode.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <Editor/EditorJointConfiguration.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeAnglePair.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeLinearFloat.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeRotation.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapPosition.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapRotation.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeTranslate.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsComponentMode, AZ::SystemAllocator, 0);
namespace SubModeData
{
const AZ::Crc32 SwitchToTranslationSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtotranslationsubmode");
static const char* TranslationTitle = "Switch to Position Mode";
static const char* TranslationToolTip = "Position Mode - Change the position of the joint.";
const AZ::Crc32 SwitchToRotationSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtorotationsubmode");
static const char* RotationTitle = "Switch to Rotation Mode";
static const char* RotationToolTip = "Rotation Mode- Change the rotation of the joint.";
const AZ::Crc32 SwitchToMaxForceSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtomaxforce");
static const char* MaxForceTitle = "Switch to Max Force Mode";
static const char* MaxForceToolTip = "Max Force Mode - Change the maximum force allowed before the joint breaks.";
const AZ::Crc32 SwitchToMaxTorqueSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtomaxtorque");
static const char* MaxTorqueTitle = "Switch to Max Torque Mode";
static const char* MaxTorqueToolTip = "Max Torque Mode - Change the maximum torque allowed before the joint breaks.";
const AZ::Crc32 SwitchToDampingSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtodamping");
static const char* DampingTitle = "Switch to Damping Mode";
static const char* DampingToolTip = "Damping Mode - Change the damping strength of the joint when beyond the limit.";
const AZ::Crc32 SwitchToStiffnessSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtostiffness");
static const char* StiffnessTitle = "Switch to Stiffness Mode";
static const char* StiffnessToolTip = "Stiffness Mode - Change the stiffness strength of the joint when beyond the limit.";
const AZ::Crc32 SwitchToTwistLimitsSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtotwistlimits");
static const char* TwistLimitsTitle = "Switch to Twist Limits Mode";
static const char* TwistLimitsToolTip = "Twist Limits Mode - Change the limits of the joint.";
const AZ::Crc32 SwitchToSwingLimitsSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtoswinglimits");
static const char* SwingLimitsTitle = "Switch to Swing Limits Mode";
static const char* SwingLimitsToolTip = "Swing Limits Mode - Change the limits of the joint.";
const AZ::Crc32 SwitchToSnapPositionSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtosnapposition");
static const char* SnapPositionTitle = "Switch to Snap Position Mode";
static const char* SnapPositionToolTip = "Snap Position Mode - Snap the position of the joint to another Entity.";
const AZ::Crc32 SwitchToSnapRotationSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.switchtosnaprotation");
static const char* SnapRotationTitle = "Switch to Snap Rotation Mode";
static const char* SnapRotationToolTip = "Snap Rotation Mode - Snap the rotation of the joint toward another Entity.";
const AZ::Crc32 ResetSubMode = AZ_CRC_CE("com.o3de.action.physx.joints.resetsubmode");
static const char* ResetTitle = "Reset Current Mode";
static const char* ResetToolTip = "Reset changes made during this mode edit.";
} // namespace ActionData
namespace Internal
{
static AzToolsFramework::ViewportUi::ButtonId RegisterClusterButton(
AzToolsFramework::ViewportUi::ClusterId clusterId, const char* iconName, const char* tooltip)
{
AzToolsFramework::ViewportUi::ButtonId buttonId;
AzToolsFramework::ViewportUi::ViewportUiRequestBus::EventResult(
buttonId, AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::CreateClusterButton, clusterId,
AZStd::string::format(":/stylesheet/img/UI20/toolbar/%s.svg", iconName));
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterButtonTooltip, clusterId, buttonId, tooltip);
return buttonId;
}
void RefreshUI()
{
// The reason this is in a free function is because ColliderComponentMode
// privately inherits from ToolsApplicationNotificationBus. Trying to invoke
// the bus inside the class scope causes the compiler to complain it's not accessible
// to due private inheritance.
// Using the global namespace operator :: should have fixed that, except there
// is a bug in the Microsoft compiler meaning it doesn't work. So this is a work around.
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(
&AzToolsFramework::ToolsApplicationNotificationBus::Events::InvalidatePropertyDisplay, AzToolsFramework::Refresh_Values);
}
} // namespace Internal
JointsComponentMode::JointsComponentMode(const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType)
: AzToolsFramework::ComponentModeFramework::EditorBaseComponentMode(entityComponentIdPair, componentType)
{
m_modeSelectionClusterIds.assign(static_cast<int>(ClusterGroups::GroupCount), AzToolsFramework::ViewportUi::InvalidClusterId);
SetupSubModes(entityComponentIdPair);
EditorJointRequestBus::Event(
entityComponentIdPair, &EditorJointRequests::SetBoolValue, JointsComponentModeCommon::ParamaterNames::ComponentMode, true);
}
JointsComponentMode::~JointsComponentMode()
{
EditorJointRequestBus::Event(
GetEntityComponentIdPair(), &EditorJointRequests::SetBoolValue, JointsComponentModeCommon::ParamaterNames::ComponentMode,
false);
TeardownSubModes();
m_subModes[m_subMode]->Teardown(GetEntityComponentIdPair());
}
void JointsComponentMode::Refresh()
{
m_subModes[m_subMode]->Refresh(GetEntityComponentIdPair());
}
AZStd::vector<AzToolsFramework::ActionOverride> JointsComponentMode::PopulateActionsImpl()
{
const AZ::EntityComponentIdPair entityComponentIdPair = GetEntityComponentIdPair();
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> subModesState;
EditorJointRequestBus::EventResult(subModesState, entityComponentIdPair, &EditorJointRequests::GetSubComponentModesState);
auto makeActionOverride = [](const AZ::EntityComponentIdPair& entityComponentIdPair, const AZ::Crc32& actionUri,
const QString& title, const QString& tip,const AZStd::function<void()>&& callback)
{
AzToolsFramework::ActionOverride actionOverride;
actionOverride.SetTitle(title);
actionOverride.SetTip(tip);
actionOverride.SetUri(actionUri);
actionOverride.SetEntityComponentIdPair(entityComponentIdPair);
actionOverride.SetCallback(callback);
return actionOverride;
};
AZStd::vector<AzToolsFramework::ActionOverride> actions;
// translation action
{
AzToolsFramework::ActionOverride translateAction = makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToTranslationSubMode,
SubModeData::TranslationTitle, SubModeData::TranslationToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::Translation,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Translation]);
});
translateAction.SetKeySequence(QKeySequence(Qt::Key_1));
actions.emplace_back(translateAction);
}
// rotation action
{
AzToolsFramework::ActionOverride rotationAction = makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToRotationSubMode,
SubModeData::RotationTitle, SubModeData::RotationToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::Rotation,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Rotation]);
});
rotationAction.SetKeySequence(QKeySequence(Qt::Key_2));
actions.emplace_back(rotationAction);
}
//setup action for other enabled options
for (auto [modeType, parameterString] : subModesState)
{
switch (modeType)
{
case JointsComponentModeCommon::SubComponentModes::ModeType::MaxForce:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToMaxForceSubMode,
SubModeData::MaxForceTitle, SubModeData::MaxForceToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::MaxForce,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::MaxForce]);
}));
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::MaxTorque:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToMaxTorqueSubMode,
SubModeData::MaxTorqueTitle, SubModeData::MaxTorqueToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::MaxTorque,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::MaxTorque]);
}));
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::Damping:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToDampingSubMode,
SubModeData::DampingTitle, SubModeData::DampingToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::Damping,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Damping]);
}));
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToStiffnessSubMode,
SubModeData::StiffnessTitle, SubModeData::StiffnessToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness]);
}));
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::TwistLimits:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToTwistLimitsSubMode,
SubModeData::TwistLimitsTitle, SubModeData::TwistLimitsToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::TwistLimits,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::TwistLimits]);
}));
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::SwingLimits:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToSwingLimitsSubMode,
SubModeData::SwingLimitsTitle, SubModeData::SwingLimitsToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::SwingLimits,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::SwingLimits]);
}));
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToSnapPositionSubMode,
SubModeData::SnapPositionTitle, SubModeData::SnapPositionToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition]);
}));
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::SnapRotation:
{
actions.emplace_back(makeActionOverride(
entityComponentIdPair, SubModeData::SwitchToSnapRotationSubMode,
SubModeData::SnapRotationTitle, SubModeData::SnapRotationToolTip,
[this]()
{
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::SnapRotation,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::SnapRotation]);
}));
}
break;
}
}
// reset values
{
AzToolsFramework::ActionOverride resetValuesAction = makeActionOverride(
entityComponentIdPair, SubModeData::ResetSubMode,
SubModeData::ResetTitle, SubModeData::ResetToolTip,
[this]()
{
ResetCurrentMode();
});
resetValuesAction.SetKeySequence(QKeySequence(Qt::Key_R));
actions.emplace_back(resetValuesAction);
}
return actions;
}
AZStd::vector<AzToolsFramework::ViewportUi::ClusterId> JointsComponentMode::PopulateViewportUiImpl()
{
return AZStd::vector<AzToolsFramework::ViewportUi::ClusterId>(m_modeSelectionClusterIds.begin(), m_modeSelectionClusterIds.end());
}
void JointsComponentMode::SetCurrentMode(JointsComponentModeCommon::SubComponentModes::ModeType newMode, ButtonData& buttonData)
{
if (auto subMode = m_subModes.find(newMode);
subMode != m_subModes.end())
{
const AZ::EntityComponentIdPair entityComponentIdPair = GetEntityComponentIdPair();
m_subModes[m_subMode]->Teardown(entityComponentIdPair);
m_subMode = newMode;
subMode->second->Setup(entityComponentIdPair);
// if this button is on a different cluster. clear the active state.
if (m_activeButton.m_clusterId != buttonData.m_clusterId)
{
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::ClearClusterActiveButton, m_activeButton.m_clusterId);
}
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterActiveButton, buttonData.m_clusterId,
buttonData.m_buttonId);
m_activeButton = buttonData;
}
else
{
AZ_Assert(false, "PhysXJoints Uninitialized joint component mode selected.");
}
}
bool JointsComponentMode::HandleMouseInteraction(const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
// Propagate mouse interaction to sub-component mode.
if (m_subModes[m_subMode])
{
m_subModes[m_subMode]->HandleMouseInteraction(mouseInteraction);
}
return false;
}
void JointsComponentMode::SetupSubModes(const AZ::EntityComponentIdPair& entityComponentIdPair)
{
//create the 3 cluster groups
for (auto& clusterId : m_modeSelectionClusterIds)
{
AzToolsFramework::ViewportUi::ViewportUiRequestBus::EventResult(
clusterId, AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::CreateCluster,
AzToolsFramework::ViewportUi::Alignment::TopLeft);
}
//retrieve the enabled sub components from the entity
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> subModesState;
EditorJointRequestBus::EventResult(subModesState, entityComponentIdPair, &EditorJointRequests::GetSubComponentModesState);
const AzToolsFramework::ViewportUi::ClusterId group1ClusterId = GetClusterId(ClusterGroups::Group1);
const AzToolsFramework::ViewportUi::ClusterId group2ClusterId = GetClusterId(ClusterGroups::Group2);
//hide cluster 2, if something is added to it. it will make is visible
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId, &AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible,
group2ClusterId, false);
const AzToolsFramework::ViewportUi::ClusterId group3ClusterId = GetClusterId(ClusterGroups::Group3);
// hide cluster 3, if something is added to it. it will make is visible
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId, &AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible,
group3ClusterId, false);
//translation and rotation are enabled for all joints in group 1
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::Translation] =
AZStd::make_unique<JointsSubComponentModeTranslation>();
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Translation] =
ButtonData{ group1ClusterId, Internal::RegisterClusterButton(group1ClusterId, "Move", SubModeData::TranslationToolTip) };
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::Rotation] = AZStd::make_unique<JointsSubComponentModeRotation>();
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Rotation] =
ButtonData{ group1ClusterId, Internal::RegisterClusterButton(group1ClusterId, "Rotate", SubModeData::RotationTitle) };
//some constants for some modes
const float ExponentBreakage = 1.0f;
const float ExponentSpring = 2.0f;
//setup the remaining modes if they're in the enabled list.
for (auto [modeType, parameterString] : subModesState)
{
switch (modeType)
{
case JointsComponentModeCommon::SubComponentModes::ModeType::MaxForce:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::MaxForce] =
AZStd::make_unique<JointsSubComponentModeLinearFloat>(
parameterString, ExponentBreakage, EditorJointConfig::s_breakageMax, EditorJointConfig::s_breakageMin);
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group3ClusterId, "joints/MaxForce", SubModeData::MaxForceToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::MaxForce] =
ButtonData{ group3ClusterId, buttonId };
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, group3ClusterId, true);
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::MaxTorque:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::MaxTorque] =
AZStd::make_unique<JointsSubComponentModeLinearFloat>(
parameterString, ExponentBreakage, EditorJointConfig::s_breakageMax, EditorJointConfig::s_breakageMin);
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group3ClusterId, "joints/MaxTorque", SubModeData::MaxTorqueToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::MaxTorque] =
ButtonData{ group3ClusterId, buttonId };
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, group3ClusterId, true);
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::Damping:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::Damping] =
AZStd::make_unique<JointsSubComponentModeLinearFloat>(
parameterString, ExponentSpring, EditorJointLimitBase::s_springMax, EditorJointLimitBase::s_springMin);
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group2ClusterId, "joints/Damping", SubModeData::DampingToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Damping] = ButtonData{ group2ClusterId, buttonId };
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, group2ClusterId, true);
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness] =
AZStd::make_unique<JointsSubComponentModeLinearFloat>(
parameterString, ExponentSpring, EditorJointLimitBase::s_springMax, EditorJointLimitBase::s_springMin);
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group2ClusterId, "joints/Stiffness", SubModeData::StiffnessToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness] =
ButtonData{ group2ClusterId, buttonId };
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, group2ClusterId, true);
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::TwistLimits:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::TwistLimits] =
AZStd::make_unique<JointsSubComponentModeAnglePair>(
parameterString,
AZ::Vector3::CreateAxisX(), // PhysX revolute joints uses the x-axis by default
EditorJointLimitPairConfig::s_angleMax, EditorJointLimitPairConfig::s_angleMin);
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group2ClusterId, "joints/TwistLimits", SubModeData::TwistLimitsToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::TwistLimits] =
ButtonData{ group2ClusterId, buttonId };
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, group2ClusterId, true);
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::SwingLimits:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::SwingLimits] =
AZStd::make_unique<JointsSubComponentModeAngleCone>(
parameterString, EditorJointLimitPairConfig::s_angleMax, EditorJointLimitPairConfig::s_angleMin);
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group2ClusterId, "joints/SwingLimits", SubModeData::SwingLimitsToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::SwingLimits] =
ButtonData{ group2ClusterId, buttonId };
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::SetClusterVisible, group2ClusterId, true);
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition] =
AZStd::make_unique<JointsSubComponentModeSnapPosition>();
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group1ClusterId, "joints/SnapPosition", SubModeData::SnapPositionToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition] =
ButtonData{ group1ClusterId, buttonId };
}
break;
case JointsComponentModeCommon::SubComponentModes::ModeType::SnapRotation:
{
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::SnapRotation] =
AZStd::make_unique<JointsSubComponentModeSnapRotation>();
const AzToolsFramework::ViewportUi::ButtonId buttonId =
Internal::RegisterClusterButton(group1ClusterId, "joints/SnapRotation", SubModeData::SnapRotationToolTip);
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::SnapRotation] =
ButtonData{ group1ClusterId, buttonId };
}
break;
}
}
//register click handler for the buttons
m_modeSelectionHandlers.push_back(AZ::Event<AzToolsFramework::ViewportUi::ButtonId>::Handler(
[this](AzToolsFramework::ViewportUi::ButtonId buttonId)
{
for (auto itr : m_buttonData)
{
if (itr.second.m_clusterId == GetClusterId(ClusterGroups::Group1) && itr.second.m_buttonId == buttonId)
{
SetCurrentMode(itr.first, itr.second);
break;
}
}
}));
m_modeSelectionHandlers.push_back(AZ::Event<AzToolsFramework::ViewportUi::ButtonId>::Handler(
[this](AzToolsFramework::ViewportUi::ButtonId buttonId)
{
for (auto itr : m_buttonData)
{
if (itr.second.m_clusterId == GetClusterId(ClusterGroups::Group2) && itr.second.m_buttonId == buttonId)
{
SetCurrentMode(itr.first, itr.second);
break;
}
}
}));
m_modeSelectionHandlers.push_back(AZ::Event<AzToolsFramework::ViewportUi::ButtonId>::Handler(
[this](AzToolsFramework::ViewportUi::ButtonId buttonId)
{
for (auto itr : m_buttonData)
{
if (itr.second.m_clusterId == GetClusterId(ClusterGroups::Group3) && itr.second.m_buttonId == buttonId)
{
SetCurrentMode(itr.first, itr.second);
break;
}
}
}));
for (int i = 0; i < static_cast<int>(ClusterGroups::GroupCount); i++)
{
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId,
&AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::RegisterClusterEventHandler, m_modeSelectionClusterIds[i],
m_modeSelectionHandlers[i]);
}
// set the translate as enabled by default.
SetCurrentMode(
JointsComponentModeCommon::SubComponentModes::ModeType::Translation,
m_buttonData[JointsComponentModeCommon::SubComponentModes::ModeType::Translation]);
m_subModes[JointsComponentModeCommon::SubComponentModes::ModeType::Translation]->Setup(GetEntityComponentIdPair());
m_subMode = JointsComponentModeCommon::SubComponentModes::ModeType::Translation;
}
void JointsComponentMode::ResetCurrentMode()
{
const AZ::EntityComponentIdPair entityComponentIdPair = GetEntityComponentIdPair();
m_subModes[m_subMode]->ResetValues(entityComponentIdPair);
m_subModes[m_subMode]->Refresh(entityComponentIdPair);
Internal::RefreshUI();
}
void JointsComponentMode::TeardownSubModes()
{
for (auto clusterid : m_modeSelectionClusterIds)
{
AzToolsFramework::ViewportUi::ViewportUiRequestBus::Event(
AzToolsFramework::ViewportUi::DefaultViewportId, &AzToolsFramework::ViewportUi::ViewportUiRequestBus::Events::RemoveCluster,
clusterid);
}
}
AzToolsFramework::ViewportUi::ClusterId JointsComponentMode::GetClusterId(ClusterGroups group)
{
return m_modeSelectionClusterIds[static_cast<int>(group)];
}
} // namespace PhysX
@@ -0,0 +1,79 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/Event.h>
#include <AzCore/Math/Uuid.h>
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzToolsFramework/ComponentMode/EditorBaseComponentMode.h>
#include <AzToolsFramework/ViewportUi/ViewportUiRequestBus.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
namespace AZ
{
class EntityComponentIdPair;
}
namespace PhysX
{
//! Class responsible for managing component mode for joints.
class JointsComponentMode final
: public AzToolsFramework::ComponentModeFramework::EditorBaseComponentMode
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsComponentMode(const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType);
~JointsComponentMode();
// EditorBaseComponentMode ...
void Refresh() override;
AZStd::vector<AzToolsFramework::ActionOverride> PopulateActionsImpl() override;
AZStd::vector<AzToolsFramework::ViewportUi::ClusterId> PopulateViewportUiImpl() override;
private:
//! Used to identify the group of component modes.
enum class ClusterGroups
{
Group1 = 0, //!< Position Joint, Rotate Joint, Snap Position, Snap Rotation.
Group2, //!< Damping, Stiffness, Twist Limits, Swing Limits.
Group3, //!< Max Force, Max Torque.
GroupCount
};
//! Used to track the cluster that a specific button is apart of.
struct ButtonData
{
AzToolsFramework::ViewportUi::ClusterId m_clusterId;
AzToolsFramework::ViewportUi::ButtonId m_buttonId;
};
void SetCurrentMode(JointsComponentModeCommon::SubComponentModes::ModeType newMode, ButtonData& buttonData);
bool HandleMouseInteraction(const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
void SetupSubModes(const AZ::EntityComponentIdPair& entityComponentIdPair);
void ResetCurrentMode();
void TeardownSubModes();
AzToolsFramework::ViewportUi::ClusterId GetClusterId(ClusterGroups group);
AZStd::fixed_vector<AzToolsFramework::ViewportUi::ClusterId, static_cast<int>(ClusterGroups::GroupCount)> m_modeSelectionClusterIds; //!< List of the cluster ui's. The sub modes are split across 3 groups and each group is it's own cluster ui.
AZStd::unordered_map<JointsComponentModeCommon::SubComponentModes::ModeType, ButtonData> m_buttonData; //!< Mapping of joint component modes to the button data.
AZStd::fixed_vector<AZ::Event<AzToolsFramework::ViewportUi::ButtonId>::Handler, static_cast<int>(ClusterGroups::GroupCount)>
m_modeSelectionHandlers; //!< Input handlers for each cluster UI.
ButtonData m_activeButton; //!< The current highlighted button data.
JointsComponentModeCommon::SubComponentModes::ModeType m_subMode = JointsComponentModeCommon::SubComponentModes::ModeType::Translation; //!< The current component mode that is active.
AZStd::unordered_map<JointsComponentModeCommon::SubComponentModes::ModeType, AZStd::unique_ptr<PhysXSubComponentModeBase>> m_subModes; //!< The logic handlers for each component mode.
};
}
@@ -0,0 +1,27 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
namespace PhysX::JointsComponentModeCommon
{
const AZStd::string_view ParamaterNames::TwistLimits = "Twist Limits";
const AZStd::string_view ParamaterNames::Damping = "Damping";
const AZStd::string_view ParamaterNames::MaxForce = "Maximum Force";
const AZStd::string_view ParamaterNames::MaxTorque = "Maximum Torque";
const AZStd::string_view ParamaterNames::Position = "Position";
const AZStd::string_view ParamaterNames::Rotation = "Rotation";
const AZStd::string_view ParamaterNames::SnapPosition = "Snap Position";
const AZStd::string_view ParamaterNames::SnapRotation = "Snap Rotation";
const AZStd::string_view ParamaterNames::Stiffness = "Stiffness";
const AZStd::string_view ParamaterNames::SwingLimit = "Swing Limits";
const AZStd::string_view ParamaterNames::Transform = "Transform";
const AZStd::string_view ParamaterNames::ComponentMode = "Component Mode";
const AZStd::string_view ParamaterNames::LeadEntity = "Lead Entity";
} // namespace PhysX::JointsComponentModeCommon
@@ -0,0 +1,70 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Quaternion.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/std/string/string.h>
#include <Editor/EditorJointCommon.h>
namespace PhysX::JointsComponentModeCommon
{
namespace SubComponentModes
{
//! Used to identify a specific sub component mode used with joints
enum class ModeType : AZ::u32
{
Translation = 0,
Rotation,
MaxForce,
MaxTorque,
Damping,
Stiffness,
TwistLimits,
SwingLimits,
SnapPosition,
SnapRotation,
ModeCount
};
//! Shared data structure used with Angle Cone and Angle Pair sub component modes.
//! Holds information about the axis and limits of the angle.
struct AngleModesSharedRotationState
{
AZ::Vector3 m_axis; //!< The Axis of rotation to apply the limits.
AZ::Quaternion m_savedOrientation = AZ::Quaternion::CreateIdentity(); //!< The angle delta of the last mouse action.
PhysX::AngleLimitsFloatPair m_valuePair; //!< the current limits of the angle.
};
} // namespace SubComponentModes
//! Name Identifiers for the joint components sub modes.
struct ParamaterNames
{
static const AZStd::string_view TwistLimits;
static const AZStd::string_view Damping;
static const AZStd::string_view MaxForce;
static const AZStd::string_view MaxTorque;
static const AZStd::string_view Position;
static const AZStd::string_view Rotation;
static const AZStd::string_view SnapPosition;
static const AZStd::string_view SnapRotation;
static const AZStd::string_view Stiffness;
static const AZStd::string_view SwingLimit;
static const AZStd::string_view Transform;
static const AZStd::string_view ComponentMode;
static const AZStd::string_view LeadEntity;
};
//! A pairing of Sub component Names, and Id.
struct SubModeParamaterState
{
SubComponentModes::ModeType m_modeType = SubComponentModes::ModeType::ModeCount; //!< The Id of the sub component mode.
AZStd::string m_parameterName; //!< The name of the sub component mode.
};
} // namespace PhysX::JointsComponentModeCommon
@@ -0,0 +1,432 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.h>
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzToolsFramework/Manipulators/PlanarManipulator.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeAngleCone, AZ::SystemAllocator, 0);
namespace Internal
{
const float ArrowLength = 2.0f;
const float ConeHeight = 3.0f;
const float XRotationManipulatorRadius = 2.0f;
const float XRotationManipulatorWidth = 0.05f;
} // namespace Internal
JointsSubComponentModeAngleCone::JointsSubComponentModeAngleCone(
const AZStd::string& propertyName, float max, float min)
: m_propertyName(propertyName)
, m_max(max)
, m_min(min)
{
}
void JointsSubComponentModeAngleCone::Setup(const AZ::EntityComponentIdPair& idPair)
{
m_entityComponentIdPair = idPair;
EditorJointRequestBus::EventResult(
m_resetPostion, m_entityComponentIdPair, &PhysX::EditorJointRequests::GetVector3Value, JointsComponentModeCommon::ParamaterNames::Position);
EditorJointRequestBus::EventResult(
m_resetRotation, m_entityComponentIdPair, &PhysX::EditorJointRequests::GetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation);
EditorJointRequestBus::EventResult(
m_resetLimits, m_entityComponentIdPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentIdPair.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentIdPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
// Initialize manipulators used to resize the base of the cone.
m_yLinearManipulator = AzToolsFramework::LinearManipulator::MakeShared(worldTransform);
m_yLinearManipulator->AddEntityComponentIdPair(m_entityComponentIdPair);
m_yLinearManipulator->SetAxis(AZ::Vector3::CreateAxisZ());
m_zLinearManipulator = AzToolsFramework::LinearManipulator::MakeShared(worldTransform);
m_zLinearManipulator->AddEntityComponentIdPair(m_entityComponentIdPair);
m_zLinearManipulator->SetAxis(AZ::Vector3::CreateAxisY());
m_yzPlanarManipulator = AzToolsFramework::PlanarManipulator::MakeShared(worldTransform);
m_yzPlanarManipulator->AddEntityComponentIdPair(m_entityComponentIdPair);
m_yzPlanarManipulator->SetAxes(AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ());
ConfigureLinearView(
Internal::ArrowLength, AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), AZ::Color(0.0f, 1.0f, 0.0f, 1.0f), AZ::Color(0.0f, 0.0f, 1.0f, 1.0f));
ConfigurePlanarView(AZ::Color(0.0f, 1.0f, 0.0f, 1.0f), AZ::Color(0.0f, 0.0f, 1.0f, 1.0f));
// Position and orientate manipulators
AZ::Transform displacementTransform = localTransform;
AZ::Vector3 displacementTranslate = localRotation.TransformVector(AZ::Vector3(Internal::ConeHeight, 0.0f, 0.0f));
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_yLinearManipulator->SetLocalTransform(displacementTransform);
m_zLinearManipulator->SetLocalTransform(displacementTransform);
m_yzPlanarManipulator->SetLocalTransform(displacementTransform);
// Initialize rotation manipulator for rotating cone
m_xRotationManipulator = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_xRotationManipulator->AddEntityComponentIdPair(m_entityComponentIdPair);
m_xRotationManipulator->SetAxis(AZ::Vector3::CreateAxisX());
m_xRotationManipulator->SetLocalTransform(localTransform);
const AZ::Color xRotationManipulatorColor = AZ::Color(1.0f, 0.0f, 0.0f, 1.0f);
m_xRotationManipulator->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_xRotationManipulator, xRotationManipulatorColor, Internal::XRotationManipulatorRadius, Internal::XRotationManipulatorWidth,
AzToolsFramework::DrawHalfDottedCircle));
AZStd::shared_ptr<JointsComponentModeCommon::SubComponentModes::AngleModesSharedRotationState> sharedRotationState =
AZStd::make_shared<JointsComponentModeCommon::SubComponentModes::AngleModesSharedRotationState>();
struct SharedState
{
AngleLimitsFloatPair m_startValues;
};
auto sharedState = AZStd::make_shared<SharedState>();
m_yLinearManipulator->InstallLeftMouseDownCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& /*action*/) mutable
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentIdPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
sharedState->m_startValues = currentValue;
});
m_yLinearManipulator->InstallMouseMoveCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& action)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentIdPair, &EditorJointRequests::GetTransformValue,
JointsComponentModeCommon::ParamaterNames::Transform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
const float axisDisplacement = action.LocalPositionOffset().Dot(localRotation.TransformVector(action.m_fixed.m_axis));
const float originalBaseY = tan(AZ::DegToRad(sharedState->m_startValues.first)) * Internal::ConeHeight;
const float newBaseY = originalBaseY + axisDisplacement;
const float newAngle = AZ::GetClamp(AZ::RadToDeg(atan(newBaseY / Internal::ConeHeight)), m_min, m_max);
EditorJointRequestBus::Event(
m_entityComponentIdPair, &EditorJointRequests::SetLinearValuePair, m_propertyName,
AngleLimitsFloatPair(newAngle, sharedState->m_startValues.second));
m_yLinearManipulator->SetBoundsDirty();
});
m_zLinearManipulator->InstallLeftMouseDownCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& /*action*/) mutable
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentIdPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
sharedState->m_startValues = currentValue;
});
m_zLinearManipulator->InstallMouseMoveCallback(
[this, sharedState](const AzToolsFramework::LinearManipulator::Action& action)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentIdPair, &EditorJointRequests::GetTransformValue,
JointsComponentModeCommon::ParamaterNames::Transform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
const float axisDisplacement = action.LocalPositionOffset().Dot(localRotation.TransformVector(action.m_fixed.m_axis));
const float originalBaseZ = tan(AZ::DegToRad(sharedState->m_startValues.second)) * Internal::ConeHeight;
const float newBaseZ = originalBaseZ + axisDisplacement;
const float newAngle = AZ::GetClamp(AZ::RadToDeg(atan(newBaseZ / Internal::ConeHeight)), m_min, m_max);
EditorJointRequestBus::Event(
m_entityComponentIdPair, &EditorJointRequests::SetLinearValuePair, m_propertyName,
AngleLimitsFloatPair(sharedState->m_startValues.first, newAngle));
m_zLinearManipulator->SetBoundsDirty();
});
m_yzPlanarManipulator->InstallLeftMouseDownCallback(
[this, sharedState]([[maybe_unused]]const AzToolsFramework::PlanarManipulator::Action& action) mutable
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentIdPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
sharedState->m_startValues = currentValue;
});
m_yzPlanarManipulator->InstallMouseMoveCallback(
[this, sharedState](const AzToolsFramework::PlanarManipulator::Action& action)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentIdPair, &EditorJointRequests::GetTransformValue,
JointsComponentModeCommon::ParamaterNames::Transform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
const float axisDisplacementY = action.LocalPositionOffset().Dot(localRotation.TransformVector(AZ::Vector3::CreateAxisY()));
const float axisDisplacementZ = action.LocalPositionOffset().Dot(localRotation.TransformVector(AZ::Vector3::CreateAxisZ()));
const float axisDisplacement = axisDisplacementZ > axisDisplacementY ? axisDisplacementZ : axisDisplacementY;
const float originalBaseY = tan(AZ::DegToRad(sharedState->m_startValues.first)) * Internal::ConeHeight;
const float newBaseY = originalBaseY + axisDisplacement;
const float newAngleY = AZ::GetClamp(AZ::RadToDeg(atan(newBaseY / Internal::ConeHeight)), m_min, m_max);
const float originalBaseZ = tan(AZ::DegToRad(sharedState->m_startValues.second)) * Internal::ConeHeight;
const float newBaseZ = originalBaseZ + axisDisplacement;
const float newAngleZ = AZ::GetClamp(AZ::RadToDeg(atan(newBaseZ / Internal::ConeHeight)), m_min, m_max);
EditorJointRequestBus::Event(
m_entityComponentIdPair, &EditorJointRequests::SetLinearValuePair, m_propertyName,
AngleLimitsFloatPair(newAngleY, newAngleZ));
m_yzPlanarManipulator->SetBoundsDirty();
});
struct SharedStateXRotate
{
AZ::Transform m_startTM;
};
auto sharedStateXRotate = AZStd::make_shared<SharedStateXRotate>();
auto mouseDownCallback = [this, sharedRotationState](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
AZ::Quaternion normalizedStart = action.m_start.m_rotation.GetNormalized();
sharedRotationState->m_axis = AZ::Vector3(normalizedStart.GetX(), normalizedStart.GetY(), normalizedStart.GetZ());
sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity();
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(
currentValue, m_entityComponentIdPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
sharedRotationState->m_valuePair = currentValue;
};
auto mouseDownRotateXCallback =
[this, sharedStateXRotate]([[maybe_unused]] const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
PhysX::EditorJointRequestBus::EventResult(
sharedStateXRotate->m_startTM, m_entityComponentIdPair, &PhysX::EditorJointRequests::GetTransformValue,
JointsComponentModeCommon::ParamaterNames::Transform);
};
m_xRotationManipulator->InstallLeftMouseDownCallback(mouseDownRotateXCallback);
m_xRotationManipulator->InstallMouseMoveCallback(
[this, sharedStateXRotate](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
AZ::Transform newTransform = AZ::Transform::CreateIdentity();
newTransform = sharedStateXRotate->m_startTM * AZ::Transform::CreateFromQuaternion(action.m_current.m_delta);
PhysX::EditorJointRequestBus::Event(
m_entityComponentIdPair, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Position,
newTransform.GetTranslation());
PhysX::EditorJointRequestBus::Event(
m_entityComponentIdPair, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation,
newTransform.GetRotation().GetEulerDegrees());
m_yLinearManipulator->SetLocalOrientation(manipulatorOrientation);
m_zLinearManipulator->SetLocalOrientation(manipulatorOrientation);
m_yLinearManipulator->SetAxis(action.m_current.m_delta.TransformVector(AZ::Vector3::CreateAxisY()));
m_zLinearManipulator->SetAxis(action.m_current.m_delta.TransformVector(AZ::Vector3::CreateAxisZ()));
m_xRotationManipulator->SetLocalOrientation(manipulatorOrientation);
m_yLinearManipulator->SetBoundsDirty();
m_zLinearManipulator->SetBoundsDirty();
m_xRotationManipulator->SetBoundsDirty();
});
m_xRotationManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_yLinearManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_zLinearManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_yzPlanarManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityComponentIdPair.GetEntityId());
Refresh(m_entityComponentIdPair);
}
void JointsSubComponentModeAngleCone::Refresh(const AZ::EntityComponentIdPair& idPair)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, idPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
float coneHeight = Internal::ConeHeight;
AngleLimitsFloatPair yzSwingAngleLimits;
EditorJointRequestBus::EventResult(yzSwingAngleLimits, idPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
// Draw inverted cone (negative cone height) if angles are larger than 90 deg.
if (yzSwingAngleLimits.first > 90.0f || yzSwingAngleLimits.second > 90.0f)
{
coneHeight = -Internal::ConeHeight;
}
// reposition manipulators
const AZ::Quaternion localRotation = localTransform.GetRotation();
const AZ::Vector3 linearManipulatorOffset =
localTransform.GetTranslation() + localRotation.TransformVector(AZ::Vector3(coneHeight, 0.0f, 0.0f));
m_xRotationManipulator->SetLocalTransform(localTransform);
localTransform.SetTranslation(linearManipulatorOffset);
m_yLinearManipulator->SetLocalTransform(localTransform);
m_zLinearManipulator->SetLocalTransform(localTransform);
m_yzPlanarManipulator->SetLocalTransform(localTransform);
}
void JointsSubComponentModeAngleCone::Teardown(const AZ::EntityComponentIdPair& idPair)
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_xRotationManipulator->RemoveEntityComponentIdPair(idPair);
m_xRotationManipulator->Unregister();
m_yLinearManipulator->RemoveEntityComponentIdPair(idPair);
m_yLinearManipulator->Unregister();
m_zLinearManipulator->RemoveEntityComponentIdPair(idPair);
m_zLinearManipulator->Unregister();
m_yzPlanarManipulator->RemoveEntityComponentIdPair(idPair);
m_yzPlanarManipulator->Unregister();
}
void JointsSubComponentModeAngleCone::ResetValues(const AZ::EntityComponentIdPair& idPair)
{
EditorJointRequestBus::Event(
idPair, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Position, m_resetPostion);
EditorJointRequestBus::Event(
idPair, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation, m_resetRotation);
EditorJointRequestBus::Event(idPair, &EditorJointRequests::SetLinearValuePair, m_propertyName, m_resetLimits);
}
void JointsSubComponentModeAngleCone::ConfigureLinearView(
float axisLength, [[maybe_unused]] const AZ::Color& axis1Color, const AZ::Color& axis2Color, const AZ::Color& axis3Color)
{
const float coneLength = 0.28f;
const float coneRadius = 0.07f;
const auto configureLinearView =
[coneLength, axisLength, coneRadius](AzToolsFramework::LinearManipulator* linearManipulator, const AZ::Color& color)
{
AzToolsFramework::ManipulatorViews views;
views.emplace_back(CreateManipulatorViewLine(
*linearManipulator, color, axisLength,
AzToolsFramework::ManipulatorLineBoundWidth(AzFramework::InvalidViewportId)));
views.emplace_back(CreateManipulatorViewCone(
*linearManipulator, color, linearManipulator->GetAxis() * (axisLength - coneLength), coneLength, coneRadius));
linearManipulator->SetViews(AZStd::move(views));
};
configureLinearView(m_yLinearManipulator.get(), axis2Color);
configureLinearView(m_zLinearManipulator.get(), axis3Color);
}
void JointsSubComponentModeAngleCone::ConfigurePlanarView(const AZ::Color& planeColor, const AZ::Color& plane2Color)
{
const float planeSize = 0.6f;
AzToolsFramework::ManipulatorViews views;
views.emplace_back(CreateManipulatorViewQuad(*m_yzPlanarManipulator, planeColor, plane2Color, planeSize));
m_yzPlanarManipulator->SetViews(AZStd::move(views));
}
void JointsSubComponentModeAngleCone::DisplayEntityViewport(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentIdPair.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentIdPair, &EditorJointRequests::GetTransformValue,
JointsComponentModeCommon::ParamaterNames::Transform);
AZ::u32 stateBefore = debugDisplay.GetState();
debugDisplay.CullOff();
debugDisplay.PushMatrix(worldTransform);
debugDisplay.PushMatrix(localTransform);
const float xAxisArrowLength = 2.0f;
debugDisplay.SetColor(AZ::Color(1.0f, 0.0f, 0.0f, 1.0f));
debugDisplay.DrawArrow(AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3(xAxisArrowLength, 0.0f, 0.0f));
AngleLimitsFloatPair yzSwingAngleLimits;
EditorJointRequestBus::EventResult(
yzSwingAngleLimits, m_entityComponentIdPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
const AZ::u32 numEllipseSamples = 16;
AZ::Vector3 ellipseSamples[numEllipseSamples];
float coneHeight = Internal::ConeHeight;
// Draw inverted cone if angles are larger than 90 deg.
if (yzSwingAngleLimits.first > 90.0f || yzSwingAngleLimits.second > 90.0f)
{
coneHeight = -Internal::ConeHeight;
}
// Compute points along perimeter of cone base
const float coney = tanf(AZ::DegToRad(yzSwingAngleLimits.first)) * coneHeight;
const float conez = tanf(AZ::DegToRad(yzSwingAngleLimits.second)) * coneHeight;
const float step = AZ::Constants::TwoPi / numEllipseSamples;
for (size_t i = 0; i < numEllipseSamples; ++i)
{
const float angleStep = step * i;
ellipseSamples[i].SetX(coneHeight);
ellipseSamples[i].SetY(conez * sin(angleStep));
ellipseSamples[i].SetZ(coney * cos(angleStep));
}
// draw cone
for (size_t i = 0; i < numEllipseSamples; ++i)
{
size_t nextIndex = i + 1;
if (i == numEllipseSamples - 1)
{
nextIndex = 0;
}
// draw cone sides
debugDisplay.SetColor(AZ::Color(1.0f, 1.0f, 1.0f, 0.2f));
debugDisplay.DrawTri(AZ::Vector3(0.0f, 0.0f, 0.0f), ellipseSamples[i], ellipseSamples[nextIndex]);
// draw parameter of cone base
debugDisplay.SetColor(AZ::Color(0.4f, 0.4f, 0.4f, 0.4f));
debugDisplay.DrawLine(ellipseSamples[i], ellipseSamples[nextIndex]);
}
// draw axis lines at base of cone, and from tip to base.
debugDisplay.SetColor(AZ::Color(0.5f, 0.5f, 0.5f, 0.6f));
debugDisplay.DrawLine(ellipseSamples[0], ellipseSamples[numEllipseSamples / 2]);
debugDisplay.DrawLine(ellipseSamples[numEllipseSamples * 3 / 4], ellipseSamples[numEllipseSamples / 4]);
debugDisplay.DrawLine(AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3(coneHeight, 0.0f, 0.0f));
debugDisplay.PopMatrix(); // pop local transform
debugDisplay.PopMatrix(); // pop world transform
debugDisplay.SetState(stateBefore);
// reposition and reorientate manipulators
Refresh(m_entityComponentIdPair);
}
} // namespace PhysX
@@ -0,0 +1,69 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/limits.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <PhysX/EditorJointBus.h>
namespace AzToolsFramework
{
class AngularManipulator;
class LinearManipulator;
class PlanarManipulator;
} // namespace AzToolsFramework
namespace PhysX
{
class JointsSubComponentModeAngleCone final
: public PhysXSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsSubComponentModeAngleCone(const AZStd::string& propertyName, float max, float min);
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
void ResetValues(const AZ::EntityComponentIdPair& idPair) override;
private:
void ConfigureLinearView(
float axisLength,
const AZ::Color& axis1Color,
const AZ::Color& axis2Color,
const AZ::Color& axis3Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
void ConfigurePlanarView(
const AZ::Color& planeColor = AZ::Color(0.0f, 1.0f, 0.0f, 0.5f),
const AZ::Color& plane2Color = AZ::Color(0.0f, 0.0f, 1.0f, 0.5f));
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
float m_max = AZStd::numeric_limits<float>::max();
float m_min = -AZStd::numeric_limits<float>::max();
AZ::EntityComponentIdPair m_entityComponentIdPair;
AZ::Vector3 m_resetPostion;
AZ::Vector3 m_resetRotation;
AngleLimitsFloatPair m_resetLimits;
AZStd::string m_propertyName;
AZStd::shared_ptr<AzToolsFramework::AngularManipulator> m_xRotationManipulator;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_yLinearManipulator;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_zLinearManipulator;
AZStd::shared_ptr<AzToolsFramework::PlanarManipulator> m_yzPlanarManipulator;
};
}
@@ -0,0 +1,305 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeAnglePair.h>
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeAnglePair, AZ::SystemAllocator, 0);
namespace Internal
{
const float Alpha = 0.6f;
const AZ::Color ColorDefault = AZ::Color(1.0f, 1.0f, 1.0f, Alpha);
const AZ::Color ColorFirst = AZ::Color(1.0f, 0.0f, 0.0f, Alpha);
const AZ::Color ColorSecond = AZ::Color(0.0f, 1.0f, 0.0f, Alpha);
const AZ::Color ColorSweepArc = AZ::Color(1.0f, 1.0f, 1.0f, Alpha);
const float SweepLineDisplaceFactor = 0.5f;
const float SweepLineThickness = 1.0f;
const float SweepLineGranularity = 1.0f;
} // namespace Internal
JointsSubComponentModeAnglePair::JointsSubComponentModeAnglePair(
const AZStd::string& propertyName, const AZ::Vector3& axis, float max, float min)
: m_propertyName(propertyName)
, m_axis(axis)
, m_firstMax(max)
, m_firstMin(min)
, m_secondMax(min)
, m_secondMin(-max)
{
}
void JointsSubComponentModeAnglePair::Setup(const AZ::EntityComponentIdPair& idPair)
{
m_entityComponentIdPair = idPair;
EditorJointRequestBus::EventResult(m_resetValue, idPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
const AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(idPair.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, idPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
AZ::Vector3 displacement = m_axis;
AZ::Transform displacementTransform = localTransform;
AZ::Vector3 displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_firstManipulator = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_firstManipulator->AddEntityComponentIdPair(idPair);
m_firstManipulator->SetAxis(m_axis);
m_firstManipulator->SetLocalTransform(displacementTransform);
displacement = -m_axis;
displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_secondManipulator = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_secondManipulator->AddEntityComponentIdPair(idPair);
m_secondManipulator->SetAxis(m_axis);
m_secondManipulator->SetLocalTransform(displacementTransform);
const float manipulatorRadius = 2.0f;
const float manipulatorWidth = 0.05f;
m_firstManipulator->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_firstManipulator, Internal::ColorFirst, manipulatorRadius, manipulatorWidth, AzToolsFramework::DrawHalfDottedCircle));
m_secondManipulator->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_secondManipulator, Internal::ColorSecond, manipulatorRadius, manipulatorWidth, AzToolsFramework::DrawHalfDottedCircle));
Refresh(idPair);
m_sharedRotationState = AZStd::make_shared<JointsComponentModeCommon::SubComponentModes::AngleModesSharedRotationState>();
auto mouseDownCallback = [this,
idPair](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
const AZ::Quaternion normalizedStart = action.m_start.m_rotation.GetNormalized();
m_sharedRotationState->m_axis = AZ::Vector3(normalizedStart.GetX(), normalizedStart.GetY(), normalizedStart.GetZ());
m_sharedRotationState->m_savedOrientation = AZ::Quaternion::CreateIdentity();
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(currentValue, idPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
m_sharedRotationState->m_valuePair = currentValue;
};
m_firstManipulator->InstallLeftMouseDownCallback(mouseDownCallback);
m_secondManipulator->InstallLeftMouseDownCallback(mouseDownCallback);
m_firstManipulator->InstallMouseMoveCallback(
[this, idPair](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
float angleDelta;
AZ::Quaternion manipulatorOrientation;
const float newValue = MouseMove(m_sharedRotationState, action, true, angleDelta, manipulatorOrientation);
if (newValue > m_firstMax || newValue < m_firstMin)
{
return;
}
m_firstManipulator->SetLocalOrientation(manipulatorOrientation);
const float newFirstValue = AZ::GetClamp(m_sharedRotationState->m_valuePair.first + angleDelta, m_firstMin, m_firstMax);
EditorJointRequestBus::Event(
idPair, &EditorJointRequests::SetLinearValuePair, m_propertyName,
AngleLimitsFloatPair(newFirstValue, m_sharedRotationState->m_valuePair.second));
});
m_secondManipulator->InstallMouseMoveCallback(
[this, idPair](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
float angleDelta;
AZ::Quaternion manipulatorOrientation;
const float newValue = MouseMove(m_sharedRotationState, action, false, angleDelta, manipulatorOrientation);
if (newValue > m_secondMax || newValue < m_secondMin)
{
return; // Not handling values exceeding limits
}
m_secondManipulator->SetLocalOrientation(manipulatorOrientation);
float newSecondValue = AZ::GetClamp(m_sharedRotationState->m_valuePair.second + angleDelta, m_secondMin, m_secondMax);
EditorJointRequestBus::Event(
idPair, &EditorJointRequests::SetLinearValuePair, m_propertyName,
AngleLimitsFloatPair(m_sharedRotationState->m_valuePair.first, newSecondValue));
});
m_firstManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
m_secondManipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(idPair.GetEntityId());
}
void JointsSubComponentModeAnglePair::Refresh(const AZ::EntityComponentIdPair& idPair)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, idPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
const AZ::Quaternion localRotation = localTransform.GetRotation();
AZ::Transform displacementTransform = localTransform;
AZ::Vector3 displacement = m_axis;
AZ::Vector3 displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_firstManipulator->SetLocalTransform(displacementTransform);
displacement = -m_axis;
displacementTranslate = localRotation.TransformVector(displacement);
displacementTransform.SetTranslation(localTransform.GetTranslation() + displacementTranslate);
m_secondManipulator->SetLocalTransform(displacementTransform);
}
void JointsSubComponentModeAnglePair::Teardown(const AZ::EntityComponentIdPair& idPair)
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_firstManipulator->RemoveEntityComponentIdPair(idPair);
m_firstManipulator->Unregister();
m_secondManipulator->RemoveEntityComponentIdPair(idPair);
m_secondManipulator->Unregister();
}
void JointsSubComponentModeAnglePair::ResetValues(const AZ::EntityComponentIdPair& idPair)
{
EditorJointRequestBus::Event(idPair, &EditorJointRequests::SetLinearValuePair, m_propertyName, m_resetValue);
m_firstManipulator->SetLocalOrientation(AZ::Quaternion::CreateFromAxisAngle(m_axis, m_resetValue.first));
m_secondManipulator->SetLocalOrientation(AZ::Quaternion::CreateFromAxisAngle(m_axis, m_resetValue.first));
}
float JointsSubComponentModeAnglePair::MouseMove(
AZStd::shared_ptr<JointsComponentModeCommon::SubComponentModes::AngleModesSharedRotationState>& sharedRotationState,
const AzToolsFramework::AngularManipulator::Action& action,
bool isFirstValue,
float& angleDelta,
AZ::Quaternion& manipulatorOrientation)
{
sharedRotationState->m_savedOrientation = action.m_current.m_delta.GetInverseFull();
angleDelta = 0.0f;
AZ::Vector3 axis = m_axis;
sharedRotationState->m_savedOrientation.ConvertToAxisAngle(axis, angleDelta);
// Polarity of axis is switched by ConvertToAxisAngle call depending on direction of rotation
if (abs(m_axis.GetX() - 1.0f) < FLT_EPSILON)
{
angleDelta = AZ::RadToDeg(angleDelta) * axis.GetX();
}
else if (abs(m_axis.GetY() - 1.0f) < FLT_EPSILON)
{
angleDelta = AZ::RadToDeg(angleDelta) * axis.GetY();
}
else if (abs(m_axis.GetZ() - 1.0f) < FLT_EPSILON)
{
angleDelta = AZ::RadToDeg(angleDelta) * axis.GetZ();
}
manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
if (isFirstValue)
{
return sharedRotationState->m_valuePair.first + angleDelta;
}
return sharedRotationState->m_valuePair.second + angleDelta;
}
void JointsSubComponentModeAnglePair::DisplayEntityViewport(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
AngleLimitsFloatPair currentValue;
EditorJointRequestBus::EventResult(currentValue, m_entityComponentIdPair, &EditorJointRequests::GetLinearValuePair, m_propertyName);
const float size = 2.0f;
AZ::Vector3 axisPoint = m_axis * size * 0.5f;
AZStd::array<AZ::Vector3, 4> points = { -axisPoint, axisPoint, axisPoint, -axisPoint };
if (abs(m_axis.GetX() - 1.0f) < FLT_EPSILON)
{
points[2].SetZ(size);
points[3].SetZ(size);
}
else if (abs(m_axis.GetY() - 1.0f) < FLT_EPSILON)
{
points[2].SetX(size);
points[3].SetX(size);
}
else if (abs(m_axis.GetZ() - 1.0f) < FLT_EPSILON)
{
points[2].SetX(size);
points[3].SetX(size);
}
AZ::u32 stateBefore = debugDisplay.GetState();
debugDisplay.CullOff();
debugDisplay.SetAlpha(Internal::Alpha);
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentIdPair.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentIdPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
debugDisplay.PushMatrix(worldTransform);
debugDisplay.PushMatrix(localTransform);
debugDisplay.SetColor(Internal::ColorSweepArc);
const AZ::Vector3 zeroVector = AZ::Vector3::CreateZero();
const AZ::Vector3 posPosition = m_axis * Internal::SweepLineDisplaceFactor;
const AZ::Vector3 negPosition = -posPosition;
debugDisplay.DrawArc(
posPosition, Internal::SweepLineThickness, -currentValue.first, currentValue.first, Internal::SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(
zeroVector, Internal::SweepLineThickness, -currentValue.first, currentValue.first, Internal::SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(
negPosition, Internal::SweepLineThickness, -currentValue.first, currentValue.first, Internal::SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(
posPosition, Internal::SweepLineThickness, 0.0f, abs(currentValue.second), Internal::SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(
zeroVector, Internal::SweepLineThickness, 0.0f, abs(currentValue.second), Internal::SweepLineGranularity, -m_axis);
debugDisplay.DrawArc(
negPosition, Internal::SweepLineThickness, 0.0f, abs(currentValue.second), Internal::SweepLineGranularity, -m_axis);
AZ::Quaternion firstRotate = AZ::Quaternion::CreateFromAxisAngle(m_axis, AZ::DegToRad(currentValue.first));
AZ::Transform firstTM = AZ::Transform::CreateFromQuaternion(firstRotate);
debugDisplay.PushMatrix(firstTM);
debugDisplay.SetColor(Internal::ColorFirst);
debugDisplay.DrawQuad(points[0], points[1], points[2], points[3]);
debugDisplay.PopMatrix();
AZ::Quaternion secondRotate = AZ::Quaternion::CreateFromAxisAngle(m_axis, AZ::DegToRad(currentValue.second));
AZ::Transform secondTM = AZ::Transform::CreateFromQuaternion(secondRotate);
debugDisplay.PushMatrix(secondTM);
debugDisplay.SetColor(Internal::ColorSecond);
debugDisplay.DrawQuad(points[0], points[1], points[2], points[3]);
debugDisplay.PopMatrix();
debugDisplay.SetColor(Internal::ColorDefault);
debugDisplay.DrawQuad(points[0], points[1], points[2], points[3]);
debugDisplay.PopMatrix(); // pop local transform
debugDisplay.PopMatrix(); // pop global transform
debugDisplay.SetState(stateBefore);
// reposition and reorientate manipulators
Refresh(m_entityComponentIdPair);
}
} // namespace PhysX
@@ -0,0 +1,70 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/limits.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
#include <PhysX/EditorJointBus.h>
namespace AZ
{
class Vector3;
} // namespace AZ
namespace PhysX
{
namespace AngleComponentModes
{
struct SharedRotationState;
} // namespace AngleComponentModes
class JointsSubComponentModeAnglePair final
: public PhysXSubComponentModeBase
, private AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsSubComponentModeAnglePair(const AZStd::string& propertyName, const AZ::Vector3& axis, float max, float min);
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
void ResetValues(const AZ::EntityComponentIdPair& idPair) override;
private:
float MouseMove(
AZStd::shared_ptr<JointsComponentModeCommon::SubComponentModes::AngleModesSharedRotationState>& sharedRotationState,
const AzToolsFramework::AngularManipulator::Action& action,
bool isFirstValue,
float& angleDelta,
AZ::Quaternion& manipulatorOrientation);
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
AZ::Vector3 m_axis = AZ::Vector3::CreateAxisX();
float m_firstMax = AZStd::numeric_limits<float>::max();
float m_firstMin = -AZStd::numeric_limits<float>::max();
float m_secondMax = AZStd::numeric_limits<float>::max();
float m_secondMin = -AZStd::numeric_limits<float>::max();
AZStd::shared_ptr<JointsComponentModeCommon::SubComponentModes::AngleModesSharedRotationState> m_sharedRotationState;
AngleLimitsFloatPair m_resetValue;
AZ::EntityComponentIdPair m_entityComponentIdPair;
AZStd::string m_propertyName;
AZStd::shared_ptr<AzToolsFramework::AngularManipulator> m_firstManipulator;
AZStd::shared_ptr<AzToolsFramework::AngularManipulator> m_secondManipulator;
};
}
@@ -0,0 +1,133 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeLinearFloat.h>
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeLinearFloat, AZ::SystemAllocator, 0);
JointsSubComponentModeLinearFloat::JointsSubComponentModeLinearFloat(
const AZStd::string& propertyName, float exponent, float max, float min)
: m_propertyName(propertyName)
, m_exponent(exponent)
, m_inverseExponent(1.0f / exponent)
, m_max(max)
, m_min(min)
{
}
void JointsSubComponentModeLinearFloat::Setup(const AZ::EntityComponentIdPair& idPair)
{
EditorJointRequestBus::EventResult(m_resetValue, idPair, &EditorJointRequests::GetLinearValue, m_propertyName);
const AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(idPair.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, idPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
m_manipulator = AzToolsFramework::LinearManipulator::MakeShared(worldTransform);
m_manipulator->AddEntityComponentIdPair(idPair);
m_manipulator->SetAxis(AZ::Vector3::CreateAxisX());
m_manipulator->SetLocalTransform(localTransform);
Refresh(idPair);
const AZ::Color manipulatorColor(0.3f, 0.3f, 0.3f, 1.0f);
const float manipulatorSize = 0.05f;
AzToolsFramework::ManipulatorViews views;
views.emplace_back(AzToolsFramework::CreateManipulatorViewQuadBillboard(manipulatorColor, manipulatorSize));
m_manipulator->SetViews(AZStd::move(views));
struct SharedState
{
float m_startingValue = 0.0f;
};
auto sharedState = AZStd::make_shared<SharedState>();
m_manipulator->InstallLeftMouseDownCallback(
[this, sharedState, idPair]([[maybe_unused]]const AzToolsFramework::LinearManipulator::Action& action) mutable
{
float currentValue = 0.0f;
EditorJointRequestBus::EventResult(currentValue, idPair, &EditorJointRequests::GetLinearValue, m_propertyName);
sharedState->m_startingValue = currentValue;
});
m_manipulator->InstallMouseMoveCallback(
[this, sharedState, idPair](const AzToolsFramework::LinearManipulator::Action& action)
{
const float axisDisplacement = action.LocalPositionOffset().Dot(action.m_fixed.m_axis);
float newValue = AZ::GetClamp(sharedState->m_startingValue + DisplacementToDeltaValue(axisDisplacement), m_min, m_max);
EditorJointRequestBus::Event(idPair, &EditorJointRequests::SetLinearValue, m_propertyName, newValue);
const AZ::Vector3 localPosition = action.LocalPosition().GetMax(AZ::Vector3(0.01f, 0.0f, 0.0f));
m_manipulator->SetLocalTransform(AZ::Transform::CreateTranslation(localPosition));
});
m_manipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
}
void JointsSubComponentModeLinearFloat::Refresh(const AZ::EntityComponentIdPair& idPair)
{
float currentValue = 0.0f;
EditorJointRequestBus::EventResult(currentValue, idPair, &EditorJointRequests::GetLinearValue, m_propertyName);
m_manipulator->SetLocalTransform(AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisX() * ValueToDisplacement(currentValue)));
}
void JointsSubComponentModeLinearFloat::Teardown(const AZ::EntityComponentIdPair& idPair)
{
m_manipulator->RemoveEntityComponentIdPair(idPair);
m_manipulator->Unregister();
m_manipulator.reset();
}
void JointsSubComponentModeLinearFloat::ResetValues(const AZ::EntityComponentIdPair& idPair)
{
EditorJointRequestBus::Event(idPair, &EditorJointRequests::SetLinearValue, m_propertyName, m_resetValue);
m_manipulator->SetLocalTransform(AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisX() * ValueToDisplacement(m_resetValue)));
}
float JointsSubComponentModeLinearFloat::DisplacementToDeltaValue(float displacement) const
{
if (displacement > 0.0f)
{
return AZStd::pow(displacement, m_exponent);
}
else if (displacement < 0.0f)
{
return -AZStd::pow(fabsf(displacement), m_exponent);
}
else
{
return 0.0f;
}
}
float JointsSubComponentModeLinearFloat::ValueToDisplacement(float value) const
{
return AZStd::pow(value, m_inverseExponent);
}
} // namespace PhysX
@@ -0,0 +1,56 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/limits.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/string/string.h>
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
namespace AZ
{
class Vector3;
} // namespace AZ
namespace AzToolsFramework
{
class LinearManipulator;
} // namespace AzToolsFramework
namespace PhysX
{
class JointsSubComponentModeLinearFloat final
: public PhysXSubComponentModeBase
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsSubComponentModeLinearFloat(
const AZStd::string& propertyName, float exponent, float max, float min);
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
void ResetValues(const AZ::EntityComponentIdPair& idPair) override;
private:
float DisplacementToDeltaValue(float displacement) const;
float ValueToDisplacement(float value) const;
float m_exponent = 1.0f;
float m_inverseExponent = 1.0f;
float m_max = AZStd::numeric_limits<float>::max();
float m_min = -AZStd::numeric_limits<float>::max();
float m_resetValue = 0.0f;
AZStd::string m_propertyName;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_manipulator;
};
}
@@ -0,0 +1,134 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeRotation.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/Color.h>
#include <AzCore/Math/Quaternion.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzFramework/Viewport/CameraState.h>
#include <AzFramework/Viewport/ViewportColors.h>
#include <AzToolsFramework/Manipulators/AngularManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorColliderComponentRequestBus.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeRotation, AZ::SystemAllocator, 0);
void JointsSubComponentModeRotation::Setup(const AZ::EntityComponentIdPair& idPair)
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(idPair.GetEntityId());
const AZ::Quaternion worldRotation = worldTransform.GetRotation();
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, idPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
EditorJointRequestBus::EventResult(
m_resetValue, idPair, &PhysX::EditorJointRequests::GetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation);
const AZStd::array<AZ::Vector3, 3> axes = { AZ::Vector3::CreateAxisX(), AZ::Vector3::CreateAxisY(), AZ::Vector3::CreateAxisZ() };
const AZStd::array<AZ::Color, 3> colors = { AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), AZ::Color(0.0f, 1.0f, 0.0f, 1.0f),
AZ::Color(0.0f, 0.0f, 1.0f, 1.0f) };
for (AZ::u32 i = 0; i < 3; ++i)
{
m_manipulators[i] = AzToolsFramework::AngularManipulator::MakeShared(worldTransform);
m_manipulators[i]->AddEntityComponentIdPair(idPair);
m_manipulators[i]->SetAxis(axes[i]);
m_manipulators[i]->SetLocalTransform(localTransform);
const float manipulatorRadius = 2.0f;
m_manipulators[i]->SetView(AzToolsFramework::CreateManipulatorViewCircle(
*m_manipulators[i], colors[i], manipulatorRadius,
AzToolsFramework::ManipulatorCicleBoundWidth(), AzToolsFramework::DrawHalfDottedCircle));
m_manipulators[i]->Register(AzToolsFramework::g_mainManipulatorManagerId);
}
InstallManipulatorMouseCallbacks(idPair);
}
void JointsSubComponentModeRotation::Refresh(const AZ::EntityComponentIdPair& idPair)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, idPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
for (auto rotationManipulator : m_manipulators)
{
rotationManipulator->SetLocalTransform(localTransform);
}
}
void JointsSubComponentModeRotation::Teardown(const AZ::EntityComponentIdPair& idPair)
{
for (auto rotationManipulator : m_manipulators)
{
rotationManipulator->RemoveEntityComponentIdPair(idPair);
rotationManipulator->Unregister();
}
}
void JointsSubComponentModeRotation::ResetValues(const AZ::EntityComponentIdPair& idPair)
{
EditorJointRequestBus::Event(
idPair, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation, m_resetValue);
const AZ::Quaternion reset = AZ::Quaternion::CreateFromEulerAnglesDegrees(m_resetValue);
for (auto manipulator : m_manipulators)
{
manipulator->SetLocalOrientation(reset);
}
}
void JointsSubComponentModeRotation::InstallManipulatorMouseCallbacks(const AZ::EntityComponentIdPair& idPair)
{
struct SharedState
{
AZ::Transform m_startTM;
};
auto sharedState = AZStd::make_shared<SharedState>();
auto mouseDownRotateXCallback =
[sharedState, idPair]([[maybe_unused]] const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
EditorJointRequestBus::EventResult(
sharedState->m_startTM, idPair, &PhysX::EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
};
for (AZ::u32 index = 0; index < 3; ++index)
{
m_manipulators[index]->InstallLeftMouseDownCallback(mouseDownRotateXCallback);
m_manipulators[index]->InstallMouseMoveCallback(
[this, index, sharedState, idPair](const AzToolsFramework::AngularManipulator::Action& action) mutable -> void
{
const AZ::Quaternion manipulatorOrientation = action.m_start.m_rotation * action.m_current.m_delta;
AZ::Transform newTransform = AZ::Transform::CreateIdentity();
newTransform = sharedState->m_startTM * AZ::Transform::CreateFromQuaternion(action.m_current.m_delta);
EditorJointRequestBus::Event(
idPair, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation,
newTransform.GetRotation().GetEulerDegrees());
m_manipulators[index]->SetLocalOrientation(manipulatorOrientation);
});
}
}
} // namespace PhysX
@@ -0,0 +1,44 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <AzCore/std/containers/array.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
namespace AzToolsFramework
{
class AngularManipulator;
}
namespace PhysX
{
class JointsSubComponentModeRotation final
: public PhysXSubComponentModeBase
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsSubComponentModeRotation() = default;
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
void ResetValues(const AZ::EntityComponentIdPair& idPair) override;
private:
void InstallManipulatorMouseCallbacks(const AZ::EntityComponentIdPair& idPair);
AZ::Vector3 m_resetValue = AZ::Vector3::CreateZero();
AZStd::array<AZStd::shared_ptr<AzToolsFramework::AngularManipulator>, 3> m_manipulators;
};
}
@@ -1,4 +1,3 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
@@ -6,49 +5,67 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Component/TransformBus.h>
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnap.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/EditorSubComponentModeSnap.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
EditorSubComponentModeSnap::EditorSubComponentModeSnap(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name)
: EditorSubComponentModeBase(entityComponentIdPair, componentType, name)
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeSnap, AZ::SystemAllocator, 0);
void JointsSubComponentModeSnap::Setup(const AZ::EntityComponentIdPair& idPair)
{
m_entityComponentId = idPair;
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
localTransform, m_entityComponentId, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
m_manipulator = AzToolsFramework::LinearManipulator::MakeShared(worldTransform);
m_manipulator->AddEntityComponentIdPair(m_entityComponentId);
m_manipulator->SetAxis(AZ::Vector3::CreateAxisX());
m_manipulator->SetLocalTransform(localTransform);
Refresh();
Refresh(idPair);
const AZ::Color manipulatorColor(0.3f, 0.3f, 0.3f, 1.0f);
const float manipulatorSize = 0.05f;
AzToolsFramework::ManipulatorViews views;
views.emplace_back(AzToolsFramework::CreateManipulatorViewQuadBillboard(manipulatorColor
, manipulatorSize));
views.emplace_back(AzToolsFramework::CreateManipulatorViewQuadBillboard(manipulatorColor, manipulatorSize));
m_manipulator->SetViews(AZStd::move(views));
m_manipulator->Register(AzToolsFramework::g_mainManipulatorManagerId);
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(m_entityComponentId.GetEntityId());
}
void EditorSubComponentModeSnap::HandleMouseInteraction(
const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction)
void JointsSubComponentModeSnap::Refresh(const AZ::EntityComponentIdPair& idPair)
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, idPair, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
m_manipulator->SetLocalTransform(localTransform);
}
void JointsSubComponentModeSnap::Teardown(const AZ::EntityComponentIdPair& idPair)
{
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
m_manipulator->RemoveEntityComponentIdPair(idPair);
m_manipulator->Unregister();
m_manipulator.reset();
}
void JointsSubComponentModeSnap::HandleMouseInteraction(const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
if (mouseInteraction.m_mouseEvent == AzToolsFramework::ViewportInteraction::MouseEvent::Move)
{
@@ -63,25 +80,36 @@ namespace PhysX
const AZ::Quaternion worldRotateInv = worldRotate.GetInverseFull();
m_manipulator->SetLocalPosition(worldRotateInv.TransformVector(m_pickedPosition - worldTransform.GetTranslation()));
m_manipulator->SetBoundsDirty();
}
}
}
void EditorSubComponentModeSnap::Refresh()
AZStd::string JointsSubComponentModeSnap::GetPickedEntityName()
{
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
m_manipulator->SetLocalTransform(localTransform);
AZStd::string pickedEntityName;
if (m_pickedEntity.IsValid())
{
AZ::ComponentApplicationBus::BroadcastResult(
pickedEntityName, &AZ::ComponentApplicationRequests::GetEntityName, m_pickedEntity);
}
return pickedEntityName;
}
void EditorSubComponentModeSnap::DisplayEntityViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay)
AZ::Vector3 JointsSubComponentModeSnap::GetPosition() const
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Quaternion worldRotate = worldTransform.GetRotation();
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
return worldTransform.GetTranslation() + worldRotate.TransformVector(localTransform.GetTranslation());
}
void JointsSubComponentModeSnap::DisplayEntityViewport(
const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay)
{
AZ::u32 stateBefore = debugDisplay.GetState();
@@ -89,11 +117,9 @@ namespace PhysX
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Transform localTransform = AZ::Transform::CreateIdentity();;
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
localTransform, m_entityComponentId, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
debugDisplay.PushMatrix(worldTransform);
debugDisplay.PushMatrix(localTransform);
@@ -104,9 +130,7 @@ namespace PhysX
AngleLimitsFloatPair yzSwingAngleLimits;
EditorJointRequestBus::EventResult(
yzSwingAngleLimits, m_entityComponentId
, &EditorJointRequests::GetLinearValuePair
, PhysX::EditorJointComponentMode::s_parameterSwingLimit);
yzSwingAngleLimits, m_entityComponentId, &EditorJointRequests::GetLinearValuePair, JointsComponentModeCommon::ParamaterNames::SwingLimit);
const AZ::u32 numEllipseSamples = 16;
AZStd::array<AZ::Vector3, numEllipseSamples> ellipseSamples;
@@ -154,8 +178,8 @@ namespace PhysX
debugDisplay.DrawLine(ellipseSamples[numEllipseSamples * 3 / 4], ellipseSamples[numEllipseSamples / 4]);
debugDisplay.DrawLine(AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3(coneHeight, 0.0f, 0.0f));
debugDisplay.PopMatrix();//pop local transform
debugDisplay.PopMatrix();//pop world transform
debugDisplay.PopMatrix(); // pop local transform
debugDisplay.PopMatrix(); // pop world transform
// draw line from joint to mouse-over entity
if (m_pickedEntity.IsValid())
@@ -173,40 +197,9 @@ namespace PhysX
debugDisplay.DrawWireBox(m_pickedEntityAabb.GetMin(), m_pickedEntityAabb.GetMax());
// draw something, e.g. an icon, to indicate type of snapping
DisplaySpecificSnapType(viewportInfo,
debugDisplay,
position,
directionNorm,
directionLength);
DisplaySpecificSnapType(viewportInfo, debugDisplay, position, directionNorm, directionLength);
}
debugDisplay.SetState(stateBefore);
}
AZStd::string EditorSubComponentModeSnap::GetPickedEntityName()
{
AZStd::string pickedEntityName;
if (m_pickedEntity.IsValid())
{
AZ::ComponentApplicationBus::BroadcastResult(pickedEntityName,
&AZ::ComponentApplicationRequests::GetEntityName,
m_pickedEntity);
}
return pickedEntityName;
}
AZ::Vector3 EditorSubComponentModeSnap::GetPosition() const
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(m_entityComponentId.GetEntityId());
AZ::Quaternion worldRotate = worldTransform.GetRotation();
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId
, &EditorJointRequests::GetTransformValue
, PhysX::EditorJointComponentMode::s_parameterTransform);
return worldTransform.GetTranslation() + worldRotate.TransformVector(localTransform.GetTranslation());
}
} // namespace PhysX
@@ -1,4 +1,3 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
@@ -6,12 +5,16 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <Editor/EditorSubComponentModeBase.h>
#include <Editor/EditorViewportEntityPicker.h>
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
namespace AzToolsFramework
{
@@ -20,48 +23,43 @@ namespace AzToolsFramework
namespace PhysX
{
/// This sub-component mode uses EditorViewportEntityPicker to get the position of an entity that the mouse is hovering over.
/// Classes inheriting from this class can use the mouse-over entity position to perform custom actions.
class EditorSubComponentModeSnap
: public PhysX::EditorSubComponentModeBase
class JointsSubComponentModeSnap
: public PhysXSubComponentModeBase
, protected AzFramework::EntityDebugDisplayEventBus::Handler
{
public:
EditorSubComponentModeSnap(
const AZ::EntityComponentIdPair& entityComponentIdPair
, const AZ::Uuid& componentType
, const AZStd::string& name);
virtual ~EditorSubComponentModeSnap() = default;
AZ_CLASS_ALLOCATOR_DECL;
// PhysX::EditorSubComponentModeBase
void HandleMouseInteraction(
const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
void Refresh() override;
JointsSubComponentModeSnap() = default;
// PhysXSubComponentModeBase ...
virtual void Setup(const AZ::EntityComponentIdPair& idPair) override;
virtual void Refresh(const AZ::EntityComponentIdPair& idPair) override;
virtual void Teardown(const AZ::EntityComponentIdPair& idPair) override;
void HandleMouseInteraction(const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) override;
protected:
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay) override;
AZStd::string GetPickedEntityName();
AZ::Vector3 GetPosition() const;
/// Override to draw specific snap type display
// AzFramework::EntityDebugDisplayEventBus
void DisplayEntityViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
//! Override to draw specific snap type display
virtual void DisplaySpecificSnapType(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
[[maybe_unused]] AzFramework::DebugDisplayRequests& debugDisplay,
[[maybe_unused]] const AZ::Vector3& jointPosition,
[[maybe_unused]] const AZ::Vector3& snapDirection,
[[maybe_unused]] float snapLength) {}
virtual void InitMouseDownCallBack() = 0;
AZStd::string GetPickedEntityName();
AZ::Vector3 GetPosition() const;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_manipulator;
[[maybe_unused]] float snapLength)
{
}
EditorViewportEntityPicker m_picker;
AZ::EntityId m_pickedEntity;
AZ::Aabb m_pickedEntityAabb = AZ::Aabb::CreateNull();
AZ::Vector3 m_pickedPosition;
AZ::EntityComponentIdPair m_entityComponentId;
AZStd::shared_ptr<AzToolsFramework::LinearManipulator> m_manipulator;
};
} // namespace PhysX
}
@@ -0,0 +1,91 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapPosition.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeSnapPosition, AZ::SystemAllocator, 0);
void JointsSubComponentModeSnapPosition::Setup(const AZ::EntityComponentIdPair& idPair)
{
JointsSubComponentModeSnap::Setup(idPair);
PhysX::EditorJointRequestBus::EventResult(
m_resetPosition, m_entityComponentId, &PhysX::EditorJointRequests::GetVector3Value, JointsComponentModeCommon::ParamaterNames::Position);
PhysX::EditorJointRequestBus::EventResult(
m_resetLeadEntity, m_entityComponentId, &PhysX::EditorJointRequests::GetEntityIdValue,
JointsComponentModeCommon::ParamaterNames::LeadEntity);
m_manipulator->InstallLeftMouseDownCallback(
[this](const AzToolsFramework::LinearManipulator::Action& /*action*/) mutable
{
if (!m_pickedEntity.IsValid())
{
return;
}
const AZ::Vector3 newLocalPosition = PhysX::Utils::ComputeJointLocalTransform(
PhysX::Utils::GetEntityWorldTransformWithScale(m_pickedEntity),
PhysX::Utils::GetEntityWorldTransformWithScale(m_entityComponentId.GetEntityId()))
.GetTranslation();
PhysX::EditorJointRequestBus::Event(
m_entityComponentId, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Position,
newLocalPosition);
const bool selectedEntityIsNotJointEntity = m_pickedEntity != m_entityComponentId.GetEntityId();
AZ_Error(
"EditorSubComponentModeSnapPosition", selectedEntityIsNotJointEntity,
"Joint's lead entity cannot be the same as the entity in which the joint resides. Select lead entity on snap failed.");
if (selectedEntityIsNotJointEntity)
{
PhysX::EditorJointRequestBus::Event(
m_entityComponentId, &PhysX::EditorJointRequests::SetEntityIdValue, JointsComponentModeCommon::ParamaterNames::LeadEntity,
m_pickedEntity);
}
});
}
void JointsSubComponentModeSnapPosition::ResetValues([[maybe_unused]]const AZ::EntityComponentIdPair& idPair)
{
PhysX::EditorJointRequestBus::Event(
m_entityComponentId, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Position, m_resetPosition);
PhysX::EditorJointRequestBus::Event(
m_entityComponentId, &PhysX::EditorJointRequests::SetEntityIdValue, JointsComponentModeCommon::ParamaterNames::LeadEntity, m_resetLeadEntity);
}
void JointsSubComponentModeSnapPosition::DisplaySpecificSnapType(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
float snapLength)
{
const float arrowLength = 1.0f;
const float iconGap = 1.0f;
const AZ::Vector3 iconPosition = jointPosition + (snapDirection * (snapLength + arrowLength + iconGap));
debugDisplay.SetColor(AZ::Colors::Red);
debugDisplay.DrawArrow(iconPosition, iconPosition + AZ::Vector3(arrowLength, 0.0f, 0.0f));
debugDisplay.SetColor(AZ::Colors::Green);
debugDisplay.DrawArrow(iconPosition, iconPosition + AZ::Vector3(0.2f, arrowLength, 0.2f));
debugDisplay.SetColor(AZ::Colors::Blue);
debugDisplay.DrawArrow(iconPosition, iconPosition + AZ::Vector3(0.0f, 0.0f, arrowLength));
}
} // namespace PhysX
@@ -0,0 +1,42 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnap.h>
namespace PhysX
{
class JointsSubComponentModeSnapPosition final
: public JointsSubComponentModeSnap
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsSubComponentModeSnapPosition() = default;
// JointsSubComponentModeSnap ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void ResetValues(const AZ::EntityComponentIdPair& idPair) override;
protected:
// JointsSubComponentModeSnap ...
void DisplaySpecificSnapType(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
float snapLength) override;
private:
AZ::Vector3 m_resetPosition;
AZ::EntityId m_resetLeadEntity;
};
}
@@ -0,0 +1,117 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapRotation.h>
#include <AzCore/Component/TransformBus.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/LinearManipulator.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeSnapRotation, AZ::SystemAllocator, 0);
void JointsSubComponentModeSnapRotation::Setup(const AZ::EntityComponentIdPair& idPair)
{
JointsSubComponentModeSnap::Setup(idPair);
PhysX::EditorJointRequestBus::EventResult(
m_resetRotation, m_entityComponentId, &PhysX::EditorJointRequests::GetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation);
m_manipulator->InstallLeftMouseDownCallback(
[this]([[maybe_unused]] const AzToolsFramework::LinearManipulator::Action& action) mutable
{
if (!m_pickedEntity.IsValid())
{
return;
}
AZ::EntityId leadEntityId;
PhysX::EditorJointRequestBus::EventResult(
leadEntityId, m_entityComponentId, &PhysX::EditorJointRequests::GetEntityIdValue,
JointsComponentModeCommon::ParamaterNames::LeadEntity);
if (leadEntityId.IsValid() && m_pickedEntity == leadEntityId)
{
AZ_Warning(
"EditorsubComponentModeSnapRotation", false,
"The entity %s is the lead of the joint. Please snap rotation (or orientation) of joint to another entity that is "
"not the lead entity.",
GetPickedEntityName().c_str());
return;
}
AZ::Transform worldTransform = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(worldTransform, m_entityComponentId.GetEntityId(), &AZ::TransformInterface::GetWorldTM);
worldTransform.ExtractUniformScale();
AZ::Transform localTransform = AZ::Transform::CreateIdentity();
EditorJointRequestBus::EventResult(
localTransform, m_entityComponentId, &EditorJointRequests::GetTransformValue, JointsComponentModeCommon::ParamaterNames::Transform);
AZ::Transform pickedEntityTransform = AZ::Transform::CreateIdentity();
AZ::TransformBus::EventResult(pickedEntityTransform, m_pickedEntity, &AZ::TransformInterface::GetWorldTM);
const AZ::Transform worldTransformInv = worldTransform.GetInverse();
const AZ::Vector3 pickedLocalPosition =
worldTransformInv.TransformVector(pickedEntityTransform.GetTranslation()) - localTransform.GetTranslation();
if (AZStd::abs(pickedLocalPosition.GetLength()) < FLT_EPSILON)
{
AZ_Warning(
"EditorsubComponentModeSnapRotation", false,
"The entity %s is too close to the joint position. Please snap rotation to an entity that is not at the position "
"of the joint.",
GetPickedEntityName().c_str());
return;
}
const AZ::Vector3 targetDirection = pickedLocalPosition.GetNormalized();
const AZ::Vector3 sourceDirection = AZ::Vector3::CreateAxisX();
const AZ::Quaternion newLocalRotation = AZ::Quaternion::CreateShortestArc(sourceDirection, targetDirection);
PhysX::EditorJointRequestBus::Event(
m_entityComponentId, &PhysX::EditorJointRequests::SetVector3Value,
JointsComponentModeCommon::ParamaterNames::Rotation // using rotation parameter name to set the local rotation value
,
newLocalRotation.GetEulerDegrees());
});
}
void JointsSubComponentModeSnapRotation::ResetValues([[maybe_unused]] const AZ::EntityComponentIdPair& idPair)
{
PhysX::EditorJointRequestBus::Event(
m_entityComponentId, &PhysX::EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Rotation, m_resetRotation);
}
void JointsSubComponentModeSnapRotation::DisplaySpecificSnapType(
[[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
float snapLength)
{
const float circleRadius = 0.5f;
const float iconGap = 1.0f;
const AZ::Vector3 iconPosition = jointPosition + (snapDirection * (snapLength + circleRadius * 2.0f + iconGap));
debugDisplay.SetColor(AZ::Colors::Red);
debugDisplay.DrawCircle(iconPosition, circleRadius, 0);
debugDisplay.SetColor(AZ::Colors::Green);
debugDisplay.DrawCircle(iconPosition, circleRadius, 1);
debugDisplay.SetColor(AZ::Colors::Blue);
debugDisplay.DrawCircle(iconPosition, circleRadius, 2);
}
} // namespace PhysX
@@ -0,0 +1,41 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnap.h>
namespace PhysX
{
class JointsSubComponentModeSnapRotation final
: public JointsSubComponentModeSnap
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsSubComponentModeSnapRotation() = default;
// JointsSubComponentModeSnap ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void ResetValues(const AZ::EntityComponentIdPair& idPair) override;
protected:
// JointsSubComponentModeSnap ...
void DisplaySpecificSnapType(
const AzFramework::ViewportInfo& viewportInfo,
AzFramework::DebugDisplayRequests& debugDisplay,
const AZ::Vector3& jointPosition,
const AZ::Vector3& snapDirection,
float snapLength) override;
private:
AZ::Vector3 m_resetRotation;
};
}
@@ -0,0 +1,90 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Editor/Source/ComponentModes/Joints/JointsSubComponentModeTranslate.h>
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzToolsFramework/Manipulators/ManipulatorManager.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <PhysX/EditorJointBus.h>
#include <Source/Utils.h>
namespace PhysX
{
AZ_CLASS_ALLOCATOR_IMPL(JointsSubComponentModeTranslation, AZ::SystemAllocator, 0);
JointsSubComponentModeTranslation::JointsSubComponentModeTranslation()
: m_manipulator(
AzToolsFramework::TranslationManipulators::Dimensions::Three, AZ::Transform::Identity(), AZ::Vector3::CreateOne())
{
}
void JointsSubComponentModeTranslation::Setup(const AZ::EntityComponentIdPair& idPair)
{
AZ::Transform worldTransform = PhysX::Utils::GetEntityWorldTransformWithoutScale(idPair.GetEntityId());
EditorJointRequestBus::EventResult(
m_resetValue, idPair, &EditorJointRequests::GetVector3Value, JointsComponentModeCommon::ParamaterNames::Position);
m_manipulator.SetSpace(worldTransform);
m_manipulator.SetLocalPosition(m_resetValue);
m_manipulator.AddEntityComponentIdPair(idPair);
m_manipulator.Register(AzToolsFramework::g_mainManipulatorManagerId);
AzToolsFramework::ConfigureTranslationManipulatorAppearance3d(&m_manipulator);
m_manipulator.InstallLinearManipulatorMouseMoveCallback(
[this, idPair](const AzToolsFramework::LinearManipulator::Action& action)
{
OnManipulatorMoved(action.LocalPosition(), idPair);
});
m_manipulator.InstallPlanarManipulatorMouseMoveCallback(
[this, idPair](const AzToolsFramework::PlanarManipulator::Action& action)
{
OnManipulatorMoved(action.LocalPosition(), idPair);
});
m_manipulator.InstallSurfaceManipulatorMouseMoveCallback(
[this, idPair](const AzToolsFramework::SurfaceManipulator::Action& action)
{
OnManipulatorMoved(action.LocalPosition(), idPair);
});
}
void JointsSubComponentModeTranslation::Refresh(const AZ::EntityComponentIdPair& idPair)
{
AZ::Vector3 localTranslation;
EditorJointRequestBus::EventResult(
localTranslation, idPair, &EditorJointRequests::GetVector3Value, JointsComponentModeCommon::ParamaterNames::Position);
m_manipulator.SetLocalPosition(localTranslation);
}
void JointsSubComponentModeTranslation::Teardown(const AZ::EntityComponentIdPair& idPair)
{
m_manipulator.RemoveEntityComponentIdPair(idPair);
m_manipulator.Unregister();
}
void JointsSubComponentModeTranslation::ResetValues(const AZ::EntityComponentIdPair& idPair)
{
PhysX::EditorJointRequestBus::Event(
idPair, &EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Position, m_resetValue);
m_manipulator.SetLocalPosition(m_resetValue);
}
void JointsSubComponentModeTranslation::OnManipulatorMoved(const AZ::Vector3& position, const AZ::EntityComponentIdPair& idPair)
{
m_manipulator.SetLocalPosition(position);
PhysX::EditorJointRequestBus::Event(
idPair, &EditorJointRequests::SetVector3Value, JointsComponentModeCommon::ParamaterNames::Position, position);
}
} // namespace PhysX
@@ -0,0 +1,43 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Math/Vector3.h>
#include <AzCore/Memory/Memory.h>
#include <AzToolsFramework/Manipulators/TranslationManipulators.h>
#include <Editor/Source/ComponentModes/PhysXSubComponentModeBase.h>
namespace AZ
{
class Vector3;
} // namespace AZ
namespace PhysX
{
class JointsSubComponentModeTranslation final
: public PhysXSubComponentModeBase
{
public:
AZ_CLASS_ALLOCATOR_DECL;
JointsSubComponentModeTranslation();
// PhysXSubComponentModeBase ...
void Setup(const AZ::EntityComponentIdPair& idPair) override;
void Refresh(const AZ::EntityComponentIdPair& idPair) override;
void Teardown(const AZ::EntityComponentIdPair& idPair) override;
void ResetValues(const AZ::EntityComponentIdPair& idPair) override;
private:
void OnManipulatorMoved(const AZ::Vector3& position, const AZ::EntityComponentIdPair& idPair);
AZ::Vector3 m_resetValue = AZ::Vector3::CreateZero();
AzToolsFramework::TranslationManipulators m_manipulator;
};
}
@@ -0,0 +1,48 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
namespace AZ
{
class EntityComponentIdPair;
} // namespace AZ
namespace AzToolsFramework::ViewportInteraction
{
struct MouseInteractionEvent;
} // namespace AzToolsFramework::ViewportInteraction
namespace PhysX
{
class PhysXSubComponentModeBase
{
public:
virtual ~PhysXSubComponentModeBase() = default;
//! Called when the mode is entered to initialize the mode.
//! @param idPair The entity/component id pair.
virtual void Setup(const AZ::EntityComponentIdPair& idPair) = 0;
//! Called when the mode needs to refresh it's values.
//! @param idPair The entity/component id pair.
virtual void Refresh(const AZ::EntityComponentIdPair& idPair) = 0;
//! Called when the mode exits to perform cleanup.
//! @param idPair The entity/component id pair.
virtual void Teardown(const AZ::EntityComponentIdPair& idPair) = 0;
//! Called when reset hot key is pressed.
//! Should reset values in the sub component mode to sensible defaults.
//! @param idPair The entity/component id pair.
virtual void ResetValues(const AZ::EntityComponentIdPair& idPair) = 0;
//! Additional mouse handling by sub-component mode. Does not absorb mouse event.
virtual void HandleMouseInteraction(
[[maybe_unused]] const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) {};
};
} // namespace PhysX
+22 -23
View File
@@ -9,59 +9,58 @@
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/EBus/EBus.h>
#include <Editor/EditorJointCommon.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
namespace PhysX
{
/// Pair of floating point values for angular limits.
using AngleLimitsFloatPair = AZStd::pair<float, float>;
/// Messages serviced by Editor Joint Components.
//! Messages serviced by Editor Joint Components.
class EditorJointRequests
: public AZ::EntityComponentBus
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
/// Get bool parameter value identified by name.
/// @return Value of bool parameter.
//! Get bool parameter value identified by name.
//! @return Value of bool parameter.
virtual bool GetBoolValue(const AZStd::string& parameterName) = 0;
/// Get entityID parameter value identified by name.
/// @return Value of entityID parameter.
//! Get entityID parameter value identified by name.
//! @return Value of entityID parameter.
virtual AZ::EntityId GetEntityIdValue(const AZStd::string& parameterName) = 0;
/// Get linear parameter value identified by name.
/// @return Value of linear value parameter.
//! Get linear parameter value identified by name.
//! @return Value of linear value parameter.
virtual float GetLinearValue(const AZStd::string& parameterName) = 0;
/// Get linear parameter value pair identified by name.
/// @return Linear parameter value pair.
//! Get linear parameter value pair identified by name.
//! @return Linear parameter value pair.
virtual AngleLimitsFloatPair GetLinearValuePair(const AZStd::string& parameterName) = 0;
/// Get vector3 value identified by name.
/// @return Vector3 parameter value.
//! Get vector3 value identified by name.
//! @return Vector3 parameter value.
virtual AZ::Vector3 GetVector3Value(const AZStd::string& parameterName) = 0;
/// Get transform value identified by name.
/// @return Transform parameter value.
//! Get transform value identified by name.
//! @return Transform parameter value.
virtual AZ::Transform GetTransformValue(const AZStd::string& parameterName) = 0;
/// Checks if parameter is used.
virtual bool IsParameterUsed(const AZStd::string& parameterName) = 0;
//! Get the Sub Component modes to enable.
virtual AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> GetSubComponentModesState() = 0;
/// Set bool parameter value identified by name.
//! Set bool parameter value identified by name.
virtual void SetBoolValue(const AZStd::string& parameterName, bool value) = 0;
/// Set entity ID parameter value identified by name.
//! Set entity ID parameter value identified by name.
virtual void SetEntityIdValue(const AZStd::string& parameterName, AZ::EntityId value) = 0;
/// Set linear parameter value identified by name.
//! Set linear parameter value identified by name.
virtual void SetLinearValue(const AZStd::string& parameterName, float value) = 0;
/// Set linear parameter value pair identified by name.
//! Set linear parameter value pair identified by name.
virtual void SetLinearValuePair(const AZStd::string& parameterName, const AngleLimitsFloatPair& valuePair) = 0;
/// Set vector3 parameter value identified by name.
//! Set vector3 parameter value identified by name.
virtual void SetVector3Value(const AZStd::string& parameterName, const AZ::Vector3& value) = 0;
};
using EditorJointRequestBus = AZ::EBus<EditorJointRequests>;
@@ -13,7 +13,8 @@
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <Source/EditorBallJointComponent.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentMode.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <Source/BallJointComponent.h>
#include <Source/Utils.h>
@@ -73,9 +74,8 @@ namespace PhysX
AzToolsFramework::EditorComponentSelectionNotificationsBus::Handler::BusConnect(entityId);
AzToolsFramework::EditorComponentSelectionRequestsBus::Handler* selection = this;
m_componentModeDelegate.ConnectWithSingleComponentMode <
EditorBallJointComponent, EditorBallJointComponentMode>(
AZ::EntityComponentIdPair(entityId, GetId()), selection);
m_componentModeDelegate.ConnectWithSingleComponentMode<EditorBallJointComponent, JointsComponentMode>(
AZ::EntityComponentIdPair(entityId, GetId()), selection);
PhysX::EditorJointRequestBus::Handler::BusConnect(AZ::EntityComponentIdPair(entityId, GetId()));
}
@@ -100,23 +100,19 @@ namespace PhysX
float EditorBallJointComponent::GetLinearValue(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxForce)
{
return m_config.m_forceMax;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxTorque)
{
return m_config.m_torqueMax;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterTolerance)
{
return m_swingLimit.m_standardLimitConfig.m_tolerance;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterDamping)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Damping)
{
return m_swingLimit.m_standardLimitConfig.m_damping;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterStiffness)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Stiffness)
{
return m_swingLimit.m_standardLimitConfig.m_stiffness;
}
@@ -126,7 +122,7 @@ namespace PhysX
AngleLimitsFloatPair EditorBallJointComponent::GetLinearValuePair(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterSwingLimit)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::SwingLimit)
{
return AngleLimitsFloatPair(m_swingLimit.m_limitY, m_swingLimit.m_limitZ);
}
@@ -134,49 +130,58 @@ namespace PhysX
return AngleLimitsFloatPair();
}
bool EditorBallJointComponent::IsParameterUsed(const AZStd::string& parameterName)
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> EditorBallJointComponent::GetSubComponentModesState()
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce
|| parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque
)
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> subModes;
subModes.emplace_back(JointsComponentModeCommon::SubModeParamaterState{
JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition,
JointsComponentModeCommon::ParamaterNames::SnapPosition });
subModes.emplace_back(JointsComponentModeCommon::SubModeParamaterState{
JointsComponentModeCommon::SubComponentModes::ModeType::SnapRotation,
JointsComponentModeCommon::ParamaterNames::SnapRotation });
if (AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> baseSubModes =
EditorJointComponent::GetSubComponentModesState();
!baseSubModes.empty())
{
return m_config.m_breakable;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterTolerance)
{
return !m_swingLimit.m_standardLimitConfig.m_isSoftLimit;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterDamping)
{
return m_swingLimit.m_standardLimitConfig.m_isSoftLimit;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterStiffness)
{
return m_swingLimit.m_standardLimitConfig.m_isSoftLimit;
subModes.insert(subModes.end(), baseSubModes.begin(), baseSubModes.end());
}
return true; // Sub-component mode always enabled unless disabled explicitly.
if (m_swingLimit.m_standardLimitConfig.m_isLimited)
{
subModes.emplace_back(
JointsComponentModeCommon::SubModeParamaterState{ JointsComponentModeCommon::SubComponentModes::ModeType::SwingLimits,
JointsComponentModeCommon::ParamaterNames::SwingLimit });
if (m_swingLimit.m_standardLimitConfig.m_isSoftLimit)
{
subModes.emplace_back(JointsComponentModeCommon::SubModeParamaterState{
JointsComponentModeCommon::SubComponentModes::ModeType::Damping, JointsComponentModeCommon::ParamaterNames::Damping });
subModes.emplace_back(
JointsComponentModeCommon::SubModeParamaterState{ JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness,
JointsComponentModeCommon::ParamaterNames::Stiffness });
}
}
return subModes;
}
void EditorBallJointComponent::SetLinearValue(const AZStd::string& parameterName, float value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxForce)
{
m_config.m_forceMax = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxTorque)
{
m_config.m_torqueMax = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterTolerance)
{
m_swingLimit.m_standardLimitConfig.m_tolerance = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterDamping)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Damping)
{
m_swingLimit.m_standardLimitConfig.m_damping = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterStiffness)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Stiffness)
{
m_swingLimit.m_standardLimitConfig.m_stiffness = value;
}
@@ -184,7 +189,7 @@ namespace PhysX
void EditorBallJointComponent::SetLinearValuePair(const AZStd::string& parameterName, const AngleLimitsFloatPair& valuePair)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterSwingLimit)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::SwingLimit)
{
m_swingLimit.m_limitY = valuePair.first;
m_swingLimit.m_limitZ = valuePair.second;
@@ -193,7 +198,7 @@ namespace PhysX
void EditorBallJointComponent::SetBoolValue(const AZStd::string& parameterName, bool value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterComponentMode)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::ComponentMode)
{
m_swingLimit.m_standardLimitConfig.m_inComponentMode = value;
m_config.m_inComponentMode = value;
@@ -202,10 +207,6 @@ namespace PhysX
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay
, AzToolsFramework::Refresh_EntireTree);
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterSelectOnSnap)
{
m_config.m_selectLeadOnSnap = value;
}
}
void EditorBallJointComponent::DisplayEntityViewport(
@@ -228,7 +229,7 @@ namespace PhysX
EditorJointRequestBus::EventResult(localTransform,
AZ::EntityComponentIdPair(entityId, GetId()),
&EditorJointRequests::GetTransformValue,
PhysX::EditorJointComponentMode::s_parameterTransform);
PhysX::JointsComponentModeCommon::ParamaterNames::Transform);
AZ::u32 stateBefore = debugDisplay.GetState();
debugDisplay.CullOff();
@@ -41,7 +41,7 @@ namespace PhysX
// PhysX::EditorJointRequests
float GetLinearValue(const AZStd::string& parameterName) override;
AngleLimitsFloatPair GetLinearValuePair(const AZStd::string& parameterName) override;
bool IsParameterUsed(const AZStd::string& parameterName) override;
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> GetSubComponentModesState() override;
void SetBoolValue(const AZStd::string& parameterName, bool value) override;
void SetLinearValue(const AZStd::string& parameterName, float value) override;
void SetLinearValuePair(const AZStd::string& parameterName, const AngleLimitsFloatPair& valuePair) override;
@@ -13,7 +13,7 @@
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <Source/EditorFixedJointComponent.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentMode.h>
#include <Source/FixedJointComponent.h>
namespace PhysX
@@ -70,9 +70,8 @@ namespace PhysX
AzToolsFramework::EditorComponentSelectionNotificationsBus::Handler::BusConnect(entityId);
AzToolsFramework::EditorComponentSelectionRequestsBus::Handler* selection = this;
m_componentModeDelegate.ConnectWithSingleComponentMode <
EditorFixedJointComponent, EditorFixedJointComponentMode>(
AZ::EntityComponentIdPair(entityId, GetId()), selection);
m_componentModeDelegate.ConnectWithSingleComponentMode<EditorFixedJointComponent, JointsComponentMode>(
AZ::EntityComponentIdPair(entityId, GetId()), selection);
PhysX::EditorJointRequestBus::Handler::BusConnect(AZ::EntityComponentIdPair(entityId, GetId()));
}
@@ -91,4 +90,9 @@ namespace PhysX
m_config.m_followerEntity = GetEntityId(); // joint is always in the same entity as the follower body.
gameEntity->CreateComponent<FixedJointComponent>(m_config.ToGameTimeConfig(), m_config.ToGenericProperties());
}
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> EditorFixedJointComponent::GetSubComponentModesState()
{
return EditorJointComponent::GetSubComponentModesState();
}
}
@@ -37,6 +37,9 @@ namespace PhysX
// EditorComponentBase
void BuildGameEntity(AZ::Entity* gameEntity) override;
// EditorJointComponent
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> GetSubComponentModesState() override;
private:
using ComponentModeDelegate = AzToolsFramework::ComponentModeFramework::ComponentModeDelegate;
ComponentModeDelegate m_componentModeDelegate; ///< Responsible for detecting ComponentMode activation
@@ -12,8 +12,9 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentMode.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <Source/EditorHingeJointComponent.h>
#include <Editor/EditorJointComponentMode.h>
#include <Source/HingeJointComponent.h>
#include <Source/Utils.h>
@@ -74,7 +75,7 @@ namespace PhysX
AzToolsFramework::EditorComponentSelectionRequestsBus::Handler* selection = this;
m_componentModeDelegate.ConnectWithSingleComponentMode <
EditorHingeJointComponent, EditorHingeJointComponentMode>(
EditorHingeJointComponent, JointsComponentMode>(
AZ::EntityComponentIdPair(entityId, GetId()), selection);
PhysX::EditorJointRequestBus::Handler::BusConnect(AZ::EntityComponentIdPair(entityId, GetId()));
@@ -100,23 +101,19 @@ namespace PhysX
float EditorHingeJointComponent::GetLinearValue(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxForce)
{
return m_config.m_forceMax;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxTorque)
{
return m_config.m_torqueMax;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterTolerance)
{
return m_angularLimit.m_standardLimitConfig.m_tolerance;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterDamping)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Damping)
{
return m_angularLimit.m_standardLimitConfig.m_damping;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterStiffness)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Stiffness)
{
return m_angularLimit.m_standardLimitConfig.m_stiffness;
}
@@ -126,7 +123,7 @@ namespace PhysX
AngleLimitsFloatPair EditorHingeJointComponent::GetLinearValuePair(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterAngularPair)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::TwistLimits)
{
return AngleLimitsFloatPair(m_angularLimit.m_limitPositive, m_angularLimit.m_limitNegative);
}
@@ -134,33 +131,41 @@ namespace PhysX
return AngleLimitsFloatPair();
}
bool EditorHingeJointComponent::IsParameterUsed(const AZStd::string& parameterName)
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> EditorHingeJointComponent::GetSubComponentModesState()
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce
|| parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque
)
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> subModes;
subModes.emplace_back(JointsComponentModeCommon::SubModeParamaterState{
JointsComponentModeCommon::SubComponentModes::ModeType::SnapPosition,
JointsComponentModeCommon::ParamaterNames::SnapPosition });
if (AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> baseSubModes =
EditorJointComponent::GetSubComponentModesState();
!baseSubModes.empty())
{
return m_config.m_breakable;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterTolerance)
{
return !m_angularLimit.m_standardLimitConfig.m_isSoftLimit;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterDamping)
{
return m_angularLimit.m_standardLimitConfig.m_isSoftLimit;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterStiffness)
{
return m_angularLimit.m_standardLimitConfig.m_isSoftLimit;
subModes.insert(subModes.end(), baseSubModes.begin(), baseSubModes.end());
}
return true; // Sub-component mode always enabled unless disabled explicitly.
if (m_angularLimit.m_standardLimitConfig.m_isLimited)
{
subModes.emplace_back(
JointsComponentModeCommon::SubModeParamaterState{ JointsComponentModeCommon::SubComponentModes::ModeType::TwistLimits,
JointsComponentModeCommon::ParamaterNames::TwistLimits });
if (m_angularLimit.m_standardLimitConfig.m_isSoftLimit)
{
subModes.emplace_back(JointsComponentModeCommon::SubModeParamaterState{
JointsComponentModeCommon::SubComponentModes::ModeType::Damping, JointsComponentModeCommon::ParamaterNames::Damping });
subModes.emplace_back(
JointsComponentModeCommon::SubModeParamaterState{ JointsComponentModeCommon::SubComponentModes::ModeType::Stiffness,
JointsComponentModeCommon::ParamaterNames::Stiffness });
}
}
return subModes;
}
void EditorHingeJointComponent::SetBoolValue(const AZStd::string& parameterName, bool value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterComponentMode)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::ComponentMode)
{
m_angularLimit.m_standardLimitConfig.m_inComponentMode = value;
m_config.m_inComponentMode = value;
@@ -169,31 +174,23 @@ namespace PhysX
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay
, AzToolsFramework::Refresh_EntireTree);
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterSelectOnSnap)
{
m_config.m_selectLeadOnSnap = value;
}
}
void EditorHingeJointComponent::SetLinearValue(const AZStd::string& parameterName, float value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxForce)
{
m_config.m_forceMax = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::MaxTorque)
{
m_config.m_torqueMax = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterTolerance)
{
m_angularLimit.m_standardLimitConfig.m_tolerance = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterDamping)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Damping)
{
m_angularLimit.m_standardLimitConfig.m_damping = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterStiffness)
else if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::Stiffness)
{
m_angularLimit.m_standardLimitConfig.m_stiffness = value;
}
@@ -201,7 +198,7 @@ namespace PhysX
void EditorHingeJointComponent::SetLinearValuePair(const AZStd::string& parameterName, const AngleLimitsFloatPair& valuePair)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterAngularPair)
if (parameterName == PhysX::JointsComponentModeCommon::ParamaterNames::TwistLimits)
{
m_angularLimit.m_limitPositive = valuePair.first;
m_angularLimit.m_limitNegative = valuePair.second;
@@ -267,7 +264,7 @@ namespace PhysX
EditorJointRequestBus::EventResult(localTransform,
AZ::EntityComponentIdPair(entityId, GetId()),
&EditorJointRequests::GetTransformValue,
PhysX::EditorJointComponentMode::s_parameterTransform);
PhysX::JointsComponentModeCommon::ParamaterNames::Transform);
debugDisplay.PushMatrix(worldTransform);
debugDisplay.PushMatrix(localTransform);
@@ -41,7 +41,7 @@ namespace PhysX
// PhysX::EditorJointRequests
float GetLinearValue(const AZStd::string& parameterName) override;
AngleLimitsFloatPair GetLinearValuePair(const AZStd::string& parameterName) override;
bool IsParameterUsed(const AZStd::string& parameterName) override;
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> GetSubComponentModesState() override;
void SetBoolValue(const AZStd::string& parameterName, bool value) override;
void SetLinearValue(const AZStd::string& parameterName, float value) override;
void SetLinearValuePair(const AZStd::string& parameterName, const AngleLimitsFloatPair& valuePair) override;
+24 -28
View File
@@ -14,7 +14,7 @@
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
#include <PhysX/Configuration/PhysXConfiguration.h>
#include <Editor/EditorJointComponentMode.h>
#include <Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h>
#include <Source/EditorColliderComponent.h>
#include <Source/EditorJointComponent.h>
#include <Source/EditorRigidBodyComponent.h>
@@ -134,21 +134,18 @@ namespace PhysX
bool EditorJointComponent::GetBoolValue(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterComponentMode)
if (parameterName == JointsComponentModeCommon::ParamaterNames::ComponentMode)
{
return m_config.m_inComponentMode;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterSelectOnSnap)
{
return m_config.m_selectLeadOnSnap;
}
AZ_Error("EditorJointComponent::GetBoolValue", false, "bool parameter not recognized: %s", parameterName.c_str());
return false;
}
AZ::EntityId EditorJointComponent::GetEntityIdValue(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterLeadEntity)
if (parameterName == JointsComponentModeCommon::ParamaterNames::LeadEntity)
{
return m_config.m_leadEntity;
}
@@ -160,11 +157,11 @@ namespace PhysX
float EditorJointComponent::GetLinearValue(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce)
if (parameterName == JointsComponentModeCommon::ParamaterNames::MaxForce)
{
return m_config.m_forceMax;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque)
else if (parameterName == JointsComponentModeCommon::ParamaterNames::MaxTorque)
{
return m_config.m_torqueMax;
}
@@ -181,7 +178,7 @@ namespace PhysX
AZ::Transform EditorJointComponent::GetTransformValue(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterTransform)
if (parameterName == JointsComponentModeCommon::ParamaterNames::Transform)
{
return AZ::Transform::CreateFromQuaternionAndTranslation(AZ::Quaternion::CreateFromEulerAnglesDegrees(m_config.m_localRotation),
m_config.m_localPosition);
@@ -192,11 +189,11 @@ namespace PhysX
AZ::Vector3 EditorJointComponent::GetVector3Value(const AZStd::string& parameterName)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterPosition)
if (parameterName == JointsComponentModeCommon::ParamaterNames::Position)
{
return m_config.m_localPosition;
}
if (parameterName == PhysX::EditorJointComponentMode::s_parameterRotation)
if (parameterName == JointsComponentModeCommon::ParamaterNames::Rotation)
{
return m_config.m_localRotation;
}
@@ -204,24 +201,27 @@ namespace PhysX
return AZ::Vector3::CreateZero();
}
bool EditorJointComponent::IsParameterUsed(const AZStd::string& parameterName)
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> EditorJointComponent::GetSubComponentModesState()
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce
|| parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque
)
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> subModes;
if (m_config.m_breakable)
{
return m_config.m_breakable;
subModes.emplace_back(JointsComponentModeCommon::SubModeParamaterState{
JointsComponentModeCommon::SubComponentModes::ModeType::MaxForce, JointsComponentModeCommon::ParamaterNames::MaxForce });
subModes.emplace_back(JointsComponentModeCommon::SubModeParamaterState{
JointsComponentModeCommon::SubComponentModes::ModeType::MaxTorque,
JointsComponentModeCommon::ParamaterNames::MaxTorque });
}
return true; // Sub-component mode always enabled unless disabled explicitly.
return subModes;
}
void EditorJointComponent::SetLinearValue(const AZStd::string& parameterName, float value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxForce)
if (parameterName == JointsComponentModeCommon::ParamaterNames::MaxForce)
{
m_config.m_forceMax = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterMaxTorque)
else if (parameterName == JointsComponentModeCommon::ParamaterNames::MaxTorque)
{
m_config.m_torqueMax = value;
}
@@ -235,11 +235,11 @@ namespace PhysX
void EditorJointComponent::SetVector3Value(const AZStd::string& parameterName, const AZ::Vector3& value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterPosition)
if (parameterName == JointsComponentModeCommon::ParamaterNames::Position)
{
m_config.m_localPosition = value;
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterRotation)
else if (parameterName == JointsComponentModeCommon::ParamaterNames::Rotation)
{
m_config.m_localRotation = value;
}
@@ -247,7 +247,7 @@ namespace PhysX
void EditorJointComponent::SetBoolValue(const AZStd::string& parameterName, bool value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterComponentMode)
if (parameterName == JointsComponentModeCommon::ParamaterNames::ComponentMode)
{
m_config.m_inComponentMode = value;
@@ -255,15 +255,11 @@ namespace PhysX
&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay
, AzToolsFramework::Refresh_EntireTree);
}
else if (parameterName == PhysX::EditorJointComponentMode::s_parameterSelectOnSnap)
{
m_config.m_selectLeadOnSnap = value;
}
}
void EditorJointComponent::SetEntityIdValue(const AZStd::string& parameterName, AZ::EntityId value)
{
if (parameterName == PhysX::EditorJointComponentMode::s_parameterLeadEntity)
if (parameterName == JointsComponentModeCommon::ParamaterNames::LeadEntity)
{
m_config.SetLeadEntityId(value);
}
@@ -56,7 +56,7 @@ namespace PhysX
AngleLimitsFloatPair GetLinearValuePair(const AZStd::string& parameterName) override;
AZ::Transform GetTransformValue(const AZStd::string& parameterName) override;
AZ::Vector3 GetVector3Value(const AZStd::string& parameterName) override;
bool IsParameterUsed(const AZStd::string& parameterName) override;
AZStd::vector<JointsComponentModeCommon::SubModeParamaterState> GetSubComponentModesState() override;
void SetBoolValue(const AZStd::string& parameterName, bool value) override;
void SetEntityIdValue(const AZStd::string& parameterName, AZ::EntityId value) override;
void SetLinearValue(const AZStd::string& parameterName, float value) override;
+22 -24
View File
@@ -82,7 +82,6 @@ set(FILES
Editor/ComboBoxEditButtonPair.cpp
Editor/ColliderComponentMode.h
Editor/ColliderComponentMode.cpp
Editor/ColliderSubComponentMode.h
Editor/ColliderOffsetMode.h
Editor/ColliderOffsetMode.cpp
Editor/ColliderBoxMode.h
@@ -99,36 +98,35 @@ set(FILES
Editor/DebugDraw.h
Editor/PolygonPrismMeshUtils.cpp
Editor/PolygonPrismMeshUtils.h
Editor/EditorJointComponentMode.cpp
Editor/EditorJointComponentMode.h
Editor/EditorJointCommon.h
Editor/EditorJointConfiguration.cpp
Editor/EditorJointConfiguration.h
Editor/EditorJointTypeDrawer.cpp
Editor/EditorJointTypeDrawer.h
Editor/EditorJointTypeDrawerBus.h
Editor/EditorSubComponentModeAngleCone.cpp
Editor/EditorSubComponentModeAngleCone.h
Editor/EditorSubComponentModeAnglePair.cpp
Editor/EditorSubComponentModeAnglePair.h
Editor/EditorSubComponentModeBase.cpp
Editor/EditorSubComponentModeBase.h
Editor/EditorSubComponentModeLinear.cpp
Editor/EditorSubComponentModeLinear.h
Editor/EditorSubComponentModeRotation.cpp
Editor/EditorSubComponentModeRotation.h
Editor/EditorSubComponentModeSnap.cpp
Editor/EditorSubComponentModeSnap.h
Editor/EditorSubComponentModeSnapPosition.cpp
Editor/EditorSubComponentModeSnapPosition.h
Editor/EditorSubComponentModeSnapRotation.cpp
Editor/EditorSubComponentModeSnapRotation.h
Editor/EditorSubComponentModeVec3.cpp
Editor/EditorSubComponentModeVec3.h
Editor/EditorViewportEntityPicker.cpp
Editor/EditorViewportEntityPicker.h
Editor/Source/Components/EditorSystemComponent.h
Editor/Source/Components/EditorSystemComponent.cpp
Editor/Source/ComponentModes/Joints/JointsComponentMode.h
Editor/Source/ComponentModes/Joints/JointsComponentMode.cpp
Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.h
Editor/Source/ComponentModes/Joints/JointsComponentModeCommon.cpp
Editor/Source/ComponentModes/PhysXSubComponentModeBase.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeAngleCone.cpp
Editor/Source/ComponentModes/Joints/JointsSubComponentModeAnglePair.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeAnglePair.cpp
Editor/Source/ComponentModes/Joints/JointsSubComponentModeLinearFloat.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeLinearFloat.cpp
Editor/Source/ComponentModes/Joints/JointsSubComponentModeRotation.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeRotation.cpp
Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnap.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnap.cpp
Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapPosition.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapPosition.cpp
Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapRotation.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeSnapRotation.cpp
Editor/Source/ComponentModes/Joints/JointsSubComponentModeTranslate.h
Editor/Source/ComponentModes/Joints/JointsSubComponentModeTranslate.cpp
Editor/Source/Configuration/PhysXEditorSettingsRegistryManager.h
Editor/Source/Configuration/PhysXEditorSettingsRegistryManager.cpp
)