Merge branch 'main' into Prism/gem-db
This commit is contained in:
@@ -4,17 +4,152 @@
|
||||
<Class name="AZStd::vector" field="Properties" type="{A8E59F8C-2F9A-525A-B549-A9E197EB9632}">
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Debug" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="1000.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Character" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.7000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.8000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.3000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="2" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="985.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.9183642 0.6973526 0.4447700 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{B072A405-BAFA-4B0A-9164-B3A424E642A9}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{FDECD8B6-5BAF-42CB-AEFE-C66E1E1CF557}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Concrete" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.8000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.9000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.3800000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="2400.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.5918365 0.4927596 0.3795224 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{A9CACCFF-E0D2-4149-8891-E92319229B2D}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Glass" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.4000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.7000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="2500.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.4825971 0.8975662 0.9523766 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{FD59CBE9-D1C4-4119-81CB-CD7AD72FC295}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Metal" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.4200000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.7800000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.4000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="8050.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.2312963 0.2312963 0.2312963 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{76CDC778-ACA9-449F-BFD7-C361F89F3207}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Plastic" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.3500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.3000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.6900000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="900.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.9394675 1.0000000 0.2735485 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{E2FFB000-D15B-4760-A819-9E490D1D3741}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Rubber" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.8500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="1200.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.1088426 0.1088426 0.1088426 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{8C7A6011-61C2-46B7-9BF4-8D4DD2A624F1}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Terrain_Dirt" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.4000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.4000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.3000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="1600.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.3333333 0.2619974 0.1973144 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{303C5A49-22F2-45A8-B24C-9F2C3CA13402}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Terrain_Grass" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.2500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.3500000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.2000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="1400.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="0.1483177 0.5986419 0.1073777 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{53733840-A095-40C4-B653-C40D233B3BE1}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Vehicle" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.2000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.3000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="1" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="1" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="140.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="1.0000000 0.0000000 0.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{4080A6D4-AF4E-41CE-B7C9-7699C07123E7}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialFromAssetConfiguration" field="element" version="1" type="{FBD76628-DE57-435E-BE00-6FFAE64DDF1D}">
|
||||
<Class name="Physics::MaterialConfiguration" field="Configuration" version="3" type="{8807CAA1-AD08-4238-8FDB-2154ADD084A1}">
|
||||
<Class name="AZStd::string" field="SurfaceType" value="Wood" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="float" field="DynamicFriction" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="StaticFriction" value="0.6000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="float" field="Restitution" value="0.6000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned char" field="FrictionCombine" value="3" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="unsigned char" field="RestitutionCombine" value="0" type="{72B9409A-7D1A-4831-9CFE-FCB3FADD3426}"/>
|
||||
<Class name="float" field="Density" value="540.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="Color" field="DebugColor" value="1.0000000 0.7318379 0.3004501 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
|
||||
</Class>
|
||||
<Class name="Physics::MaterialId" field="UID" version="1" type="{744CCE6C-9F69-4E2F-B950-DAB8514F870B}">
|
||||
<Class name="AZ::Uuid" field="MaterialId" value="{6ACE67AA-CB32-41CD-8740-58371CCCD3F3}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
|
||||
@@ -77,6 +77,27 @@
|
||||
#endif // defined(AZ_ENABLE_DEBUG_TOOLS)
|
||||
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
static void PrintEntityName(const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (arguments.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto entityIdStr = AZStd::string(arguments.front());
|
||||
const auto entityIdValue = AZStd::stoull(entityIdStr);
|
||||
|
||||
AZStd::string entityName;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(
|
||||
entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, AZ::EntityId(entityIdValue));
|
||||
|
||||
AZ_Printf("Entity Debug", "EntityId: %" PRIu64 ", Entity Name: %s", entityIdValue, entityName.c_str());
|
||||
}
|
||||
|
||||
AZ_CONSOLEFREEFUNC(
|
||||
PrintEntityName, AZ::ConsoleFunctorFlags::Null, "Parameter: EntityId value, Prints the name of the entity to the console");
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace AzFramework
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 6.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
@@ -37,7 +37,6 @@ namespace AzFramework
|
||||
AZ_CVAR(float, ed_cameraSystemPanSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(bool, ed_cameraSystemPanInvertX, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(bool, ed_cameraSystemPanInvertY, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemLookDeadzone, 2.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
@@ -303,6 +303,45 @@ namespace AzToolsFramework
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrefabLoader::SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath)
|
||||
{
|
||||
AZ_Assert(absolutePath.IsAbsolute(), "SaveTemplateToFile requires an absolute path for saving the initial prefab file.");
|
||||
|
||||
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
|
||||
if (!domAndFilepath)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify that the absolute path provided to this matches the relative path saved in the template.
|
||||
// Otherwise, the saved prefab won't be able to be loaded.
|
||||
auto relativePath = GenerateRelativePath(absolutePath);
|
||||
if (relativePath != domAndFilepath->second)
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"PrefabLoader::SaveTemplateToFile - "
|
||||
"Failed to save template '%s' to location '%.*s'."
|
||||
"Error: Relative path '%.*s' for location didn't match template name.",
|
||||
domAndFilepath->second.c_str(), AZ_STRING_ARG(absolutePath.Native()), AZ_STRING_ARG(relativePath.Native()));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto outcome = AzFramework::FileFunc::WriteJsonFile(domAndFilepath->first, absolutePath);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
AZ_Error(
|
||||
"Prefab", false,
|
||||
"PrefabLoader::SaveTemplateToFile - "
|
||||
"Failed to save template '%s' to location '%.*s'."
|
||||
"Error: %s",
|
||||
domAndFilepath->second.c_str(), AZ_STRING_ARG(absolutePath.Native()), outcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PrefabLoader::SaveTemplateToString(TemplateId templateId, AZStd::string& output)
|
||||
{
|
||||
const auto& domAndFilepath = StoreTemplateIntoFileFormat(templateId);
|
||||
|
||||
@@ -72,6 +72,16 @@ namespace AzToolsFramework
|
||||
*/
|
||||
bool SaveTemplate(TemplateId templateId) override;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template to the provided absolute source path, which needs to match the relative path in the template.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
* into a source path and patches.
|
||||
* @param templateId Id of the template to be saved
|
||||
* @param absolutePath Absolute path to save the file to
|
||||
* @return bool on whether the operation succeeded or not
|
||||
*/
|
||||
bool SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath) override;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template into the provided output string.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
|
||||
@@ -60,6 +60,16 @@ namespace AzToolsFramework
|
||||
*/
|
||||
virtual bool SaveTemplate(TemplateId templateId) = 0;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template to the provided absolute source path, which needs to match the relative path in the template.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
* into a source path and patches.
|
||||
* @param templateId Id of the template to be saved
|
||||
* @param absolutePath Absolute path to save the file to
|
||||
* @return bool on whether the operation succeeded or not
|
||||
*/
|
||||
virtual bool SaveTemplateToFile(TemplateId templateId, AZ::IO::PathView absolutePath) = 0;
|
||||
|
||||
/**
|
||||
* Saves a Prefab Template into the provided output string.
|
||||
* Converts Prefab Template form into .prefab form by collapsing nested Template info
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace AzToolsFramework
|
||||
m_prefabUndoCache.Destroy();
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath)
|
||||
PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath)
|
||||
{
|
||||
EntityList inputEntityList, topLevelEntities;
|
||||
AZ::EntityId commonRootEntityId;
|
||||
@@ -76,6 +76,8 @@ namespace AzToolsFramework
|
||||
return findCommonRootOutcome;
|
||||
}
|
||||
|
||||
AZ_Assert(absolutePath.IsAbsolute(), "CreatePrefab requires an absolute path for saving the initial prefab file.");
|
||||
|
||||
InstanceOptionalReference instanceToCreate;
|
||||
{
|
||||
// Initialize Undo Batch object
|
||||
@@ -144,7 +146,8 @@ namespace AzToolsFramework
|
||||
|
||||
// Create the Prefab
|
||||
instanceToCreate = prefabEditorEntityOwnershipInterface->CreatePrefab(
|
||||
entities, AZStd::move(instancePtrs), filePath, commonRootEntityOwningInstance);
|
||||
entities, AZStd::move(instancePtrs), m_prefabLoaderInterface->GenerateRelativePath(absolutePath),
|
||||
commonRootEntityOwningInstance);
|
||||
|
||||
if (!instanceToCreate)
|
||||
{
|
||||
@@ -254,7 +257,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
// Save Template to file
|
||||
m_prefabLoaderInterface->SaveTemplate(instanceToCreate->get().GetTemplateId());
|
||||
m_prefabLoaderInterface->SaveTemplateToFile(instanceToCreate->get().GetTemplateId(), absolutePath);
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace AzToolsFramework
|
||||
void UnregisterPrefabPublicHandlerInterface();
|
||||
|
||||
// PrefabPublicInterface...
|
||||
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) override;
|
||||
PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath) override;
|
||||
PrefabOperationResult InstantiatePrefab(AZStd::string_view filePath, AZ::EntityId parent, const AZ::Vector3& position) override;
|
||||
PrefabOperationResult SavePrefab(AZ::IO::Path filePath) override;
|
||||
PrefabEntityResult CreateEntity(AZ::EntityId parentId, const AZ::Vector3& position) override;
|
||||
|
||||
@@ -46,10 +46,10 @@ namespace AzToolsFramework
|
||||
* Create a prefab out of the entities provided, at the path provided.
|
||||
* Automatically detects descendants of entities, and discerns between entities and child instances.
|
||||
* @param entityIds The entities that should form the new prefab (along with their descendants).
|
||||
* @param filePath The path for the new prefab file.
|
||||
* @param filePath The absolute path for the new prefab file.
|
||||
* @return An outcome object; on failure, it comes with an error message detailing the cause of the error.
|
||||
*/
|
||||
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView filePath) = 0;
|
||||
virtual PrefabOperationResult CreatePrefab(const AZStd::vector<AZ::EntityId>& entityIds, AZ::IO::PathView absolutePath) = 0;
|
||||
|
||||
/**
|
||||
* Instantiate a prefab from a prefab file.
|
||||
|
||||
+1
-2
@@ -333,8 +333,7 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(
|
||||
selectedEntities, s_prefabLoaderInterface->GenerateRelativePath(prefabFilePath.data()));
|
||||
auto createPrefabOutcome = s_prefabPublicInterface->CreatePrefab(selectedEntities, prefabFilePath.data());
|
||||
|
||||
if (!createPrefabOutcome.IsSuccess())
|
||||
{
|
||||
|
||||
@@ -15,14 +15,14 @@ android {
|
||||
${SIGNING_CONFIGS}
|
||||
compileSdkVersion sdkVer
|
||||
buildToolsVersion buildToolsVer
|
||||
|
||||
ndkVersion ndkPlatformVer
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
checkReleaseBuilds false
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion ndkPlatformVer
|
||||
minSdkVersion minSdkVer
|
||||
targetSdkVersion sdkVer
|
||||
${NATIVE_CMAKE_SECTION_DEFAULT_CONFIG}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,5 @@
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
# ${GENERATION_TIMESTAMP}
|
||||
ndk.dir=${ANDROID_NDK_PATH}
|
||||
sdk.dir=${ANDROID_SDK_PATH}
|
||||
${CMAKE_DIR_LINE}
|
||||
|
||||
@@ -12,10 +12,9 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.4'
|
||||
classpath 'com.android.tools.build:gradle:${ANDROID_GRADLE_PLUGIN_VERSION}'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
@@ -26,14 +25,14 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
ext {
|
||||
minSdkVer = ${MIN_SDK_VER}
|
||||
sdkVer = ${SDK_VER}
|
||||
ndkPlatformVer = ${NDK_PLATFORM_VER}
|
||||
ndkPlatformVer = '${NDK_VERSION}'
|
||||
buildToolsVer = '${SDK_BUILD_TOOL_VER}'
|
||||
lyEngineRoot = '${LY_ENGINE_ROOT}'
|
||||
}
|
||||
|
||||
@@ -13,11 +13,6 @@
|
||||
"displayName": "Metallic",
|
||||
"description": "Properties for configuring whether the surface is metallic or not."
|
||||
},
|
||||
{
|
||||
"id": "anisotropy",
|
||||
"displayName": "Anisotropic Material Response",
|
||||
"description": "How much is this material response anisotropic."
|
||||
},
|
||||
{
|
||||
"id": "roughness",
|
||||
"displayName": "Roughness",
|
||||
@@ -28,46 +23,11 @@
|
||||
"displayName": "Specular Reflectance f0",
|
||||
"description": "The constant f0 represents the specular reflectance at normal incidence (Fresnel 0 Angle). Used to adjust reflectance of non-metal surfaces."
|
||||
},
|
||||
{
|
||||
"id": "clearCoat",
|
||||
"displayName": "Clear Coat",
|
||||
"description": "Properties for configuring gloss clear coat"
|
||||
},
|
||||
{
|
||||
"id": "normal",
|
||||
"displayName": "Normal",
|
||||
"description": "Properties related to configuring surface normal."
|
||||
},
|
||||
{
|
||||
"id": "opacity",
|
||||
"displayName": "Opacity",
|
||||
"description": "Properties for configuring the materials transparency."
|
||||
},
|
||||
{
|
||||
"id": "uv",
|
||||
"displayName": "UVs",
|
||||
"description": "Properties for configuring UV transforms."
|
||||
},
|
||||
{
|
||||
"id": "occlusion",
|
||||
"displayName": "Occlusion",
|
||||
"description": "Properties for baked textures that represent geometric occlusion of light."
|
||||
},
|
||||
{
|
||||
"id": "emissive",
|
||||
"displayName": "Emissive",
|
||||
"description": "Properties to add light emission, independent of other lights in the scene."
|
||||
},
|
||||
{
|
||||
"id": "parallax",
|
||||
"displayName": "Parallax Mapping",
|
||||
"description": "Properties for parallax effect produced by depthmap."
|
||||
},
|
||||
{
|
||||
"id": "subsurfaceScattering",
|
||||
"displayName": "Subsurface Scattering",
|
||||
"description": "Properties for configuring subsurface scattering effects."
|
||||
},
|
||||
{
|
||||
"id": "detailLayerGroup",
|
||||
"displayName": "Detail Layer",
|
||||
@@ -78,6 +38,46 @@
|
||||
"displayName": "Detail Layer UV",
|
||||
"description": "Properties for modifying detail layer UV."
|
||||
},
|
||||
{
|
||||
"id": "anisotropy",
|
||||
"displayName": "Anisotropic Material Response",
|
||||
"description": "How much is this material response anisotropic."
|
||||
},
|
||||
{
|
||||
"id": "occlusion",
|
||||
"displayName": "Occlusion",
|
||||
"description": "Properties for baked textures that represent geometric occlusion of light."
|
||||
},
|
||||
{
|
||||
"id": "emissive",
|
||||
"displayName": "Emissive",
|
||||
"description": "Properties to add light emission, independent of other lights in the scene."
|
||||
},
|
||||
{
|
||||
"id": "subsurfaceScattering",
|
||||
"displayName": "Subsurface Scattering",
|
||||
"description": "Properties for configuring subsurface scattering effects."
|
||||
},
|
||||
{
|
||||
"id": "clearCoat",
|
||||
"displayName": "Clear Coat",
|
||||
"description": "Properties for configuring gloss clear coat"
|
||||
},
|
||||
{
|
||||
"id": "parallax",
|
||||
"displayName": "Displacement",
|
||||
"description": "Properties for parallax effect produced by a height map."
|
||||
},
|
||||
{
|
||||
"id": "opacity",
|
||||
"displayName": "Opacity",
|
||||
"description": "Properties for configuring the materials transparency."
|
||||
},
|
||||
{
|
||||
"id": "uv",
|
||||
"displayName": "UVs",
|
||||
"description": "Properties for configuring UV transforms."
|
||||
},
|
||||
{
|
||||
// Note: this property group is used in the DiffuseGlobalIllumination pass and not by the main forward shader
|
||||
"id": "irradiance",
|
||||
@@ -86,7 +86,7 @@
|
||||
},
|
||||
{
|
||||
"id": "general",
|
||||
"displayName": "General",
|
||||
"displayName": "General Settings",
|
||||
"description": "General settings."
|
||||
}
|
||||
],
|
||||
@@ -197,7 +197,7 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"displayName": "Texture",
|
||||
"description": "Base color texture map",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
@@ -208,14 +208,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map.",
|
||||
"description": "Whether to use the texture.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Base color texture map UV set",
|
||||
"description": "Base color map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -227,7 +227,7 @@
|
||||
{
|
||||
"id": "textureBlendMode",
|
||||
"displayName": "Texture Blend Mode",
|
||||
"description": "Selects the equation to use when combining Color, Factor, and Texture Map.",
|
||||
"description": "Selects the equation to use when combining Color, Factor, and Texture.",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "Multiply", "LinearLight", "Lerp", "Overlay" ],
|
||||
"defaultValue": "Multiply",
|
||||
@@ -253,7 +253,7 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"displayName": "Texture",
|
||||
"description": "",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
@@ -264,14 +264,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Metallic texture map UV set",
|
||||
"description": "Metallic map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -284,8 +284,8 @@
|
||||
"roughness": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface roughness.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface roughness.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -295,14 +295,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Roughness texture map UV set",
|
||||
"description": "Roughness map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -315,7 +315,7 @@
|
||||
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
|
||||
"id": "lowerBound",
|
||||
"displayName": "Lower Bound",
|
||||
"description": "The roughness value that corresponds to black in the texture map.",
|
||||
"description": "The roughness value that corresponds to black in the texture.",
|
||||
"type": "Float",
|
||||
"defaultValue": 0.0,
|
||||
"min": 0.0,
|
||||
@@ -329,7 +329,7 @@
|
||||
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
|
||||
"id": "upperBound",
|
||||
"displayName": "Upper Bound",
|
||||
"description": "The roughness value that corresponds to white in the texture map.",
|
||||
"description": "The roughness value that corresponds to white in the texture.",
|
||||
"type": "Float",
|
||||
"defaultValue": 1.0,
|
||||
"min": 0.0,
|
||||
@@ -409,8 +409,8 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface reflectance.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface reflectance.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -420,14 +420,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Specular reflection texture map UV set",
|
||||
"description": "Specular reflection map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -472,7 +472,7 @@
|
||||
{
|
||||
"id": "influenceMap",
|
||||
"displayName": " Influence Map",
|
||||
"description": "Strength factor texture map",
|
||||
"description": "Strength factor texture",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -482,14 +482,14 @@
|
||||
{
|
||||
"id": "useInfluenceMap",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "influenceMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Strength factor texture map UV set",
|
||||
"description": "Strength factor map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -514,7 +514,7 @@
|
||||
{
|
||||
"id": "roughnessMap",
|
||||
"displayName": " Roughness Map",
|
||||
"description": "Roughness texture map",
|
||||
"description": "Texture for defining surface roughness",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -524,14 +524,14 @@
|
||||
{
|
||||
"id": "useRoughnessMap",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the roughness value.",
|
||||
"description": "Whether to use the texture, or just default to the roughness value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "roughnessMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Roughness texture map UV set",
|
||||
"description": "Roughness map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -573,7 +573,7 @@
|
||||
{
|
||||
"id": "normalMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Normal texture map UV set",
|
||||
"description": "Normal map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -586,8 +586,8 @@
|
||||
"normal": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface normal direction.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface normal direction.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -597,14 +597,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just rely on vertex normals.",
|
||||
"description": "Whether to use the texture, or just rely on vertex normals.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Normal texture map UV set",
|
||||
"description": "Normal map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -653,7 +653,7 @@
|
||||
{
|
||||
"id": "mode",
|
||||
"displayName": "Opacity Mode",
|
||||
"description": "Opacity mode for this texture.",
|
||||
"description": "Indicates the general approach how transparency is to be applied.",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "Opaque", "Cutout", "Blended", "TintedTransparent" ],
|
||||
"defaultValue": "Opaque",
|
||||
@@ -665,7 +665,7 @@
|
||||
{
|
||||
"id": "alphaSource",
|
||||
"displayName": "Alpha Source",
|
||||
"description": "Source texture of alpha value.",
|
||||
"description": "Indicates whether to get the opacity texture from the Base Color map (Packed) or from a separate greyscale texture (Split).",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "Packed", "Split", "None" ],
|
||||
"defaultValue": "Packed",
|
||||
@@ -676,8 +676,8 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface opacity.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface opacity.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -687,7 +687,7 @@
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Opacity texture map UV set",
|
||||
"description": "Opacity map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -782,7 +782,7 @@
|
||||
{
|
||||
"id": "diffuseTextureMap",
|
||||
"displayName": "Diffuse AO",
|
||||
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
|
||||
"description": "Texture for defining occlusion area for diffuse ambient lighting.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -792,14 +792,14 @@
|
||||
{
|
||||
"id": "diffuseUseTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the Diffuse AO texture map.",
|
||||
"description": "Whether to use the Diffuse AO map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "diffuseTextureMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Diffuse AO texture map UV set.",
|
||||
"description": "Diffuse AO map UV set.",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -824,7 +824,7 @@
|
||||
{
|
||||
"id": "specularTextureMap",
|
||||
"displayName": "Specular Cavity",
|
||||
"description": "Texture map for defining occlusion area for specular lighting.",
|
||||
"description": "Texture for defining occlusion area for specular lighting.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -834,14 +834,14 @@
|
||||
{
|
||||
"id": "specularUseTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the Specular Cavity texture map.",
|
||||
"description": "Whether to use the Specular Cavity map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "specularTextureMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Specular Cavity texture map UV set.",
|
||||
"description": "Specular Cavity map UV set.",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -904,8 +904,8 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining emissive area.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining emissive area.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -915,14 +915,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map.",
|
||||
"description": "Whether to use the texture.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Emissive texture map UV set",
|
||||
"description": "Emissive map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -935,8 +935,8 @@
|
||||
"parallax": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Heightmap",
|
||||
"description": "Displacement heightmap to create parallax effect.",
|
||||
"displayName": "Height Map",
|
||||
"description": "Displacement height map to create parallax effect.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -946,14 +946,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the heightmap.",
|
||||
"description": "Whether to use the height map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Heightmap UV set",
|
||||
"description": "Height map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -964,8 +964,8 @@
|
||||
},
|
||||
{
|
||||
"id": "factor",
|
||||
"displayName": "Heightmap Scale",
|
||||
"description": "The total height of the heightmap in local model units.",
|
||||
"displayName": "Height Map Scale",
|
||||
"description": "The total height of the height map in local model units.",
|
||||
"type": "Float",
|
||||
"defaultValue": 0.05,
|
||||
"min": 0.0,
|
||||
@@ -1026,7 +1026,7 @@
|
||||
{
|
||||
"id": "showClipping",
|
||||
"displayName": "Show Clipping",
|
||||
"description": "Highlight areas where the heightmap is clipped by the mesh surface.",
|
||||
"description": "Highlight areas where the height map is clipped by the mesh surface.",
|
||||
"type": "Bool",
|
||||
"defaultValue": false,
|
||||
"connection": {
|
||||
@@ -1063,7 +1063,7 @@
|
||||
{
|
||||
"id": "influenceMap",
|
||||
"displayName": " Influence Map",
|
||||
"description": "Use texture map to control the strength of subsurface scattering",
|
||||
"description": "Texture for controlling the strength of subsurface scattering",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -1073,7 +1073,7 @@
|
||||
{
|
||||
"id": "useInfluenceMap",
|
||||
"displayName": " Use Influence Map",
|
||||
"description": "Whether to use the texture map as influence mask.",
|
||||
"description": "Whether to use the influence map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
@@ -1142,7 +1142,7 @@
|
||||
{
|
||||
"id": "thicknessMap",
|
||||
"displayName": " Thickness Map",
|
||||
"description": "Use a greyscale texture for per pixel thickness",
|
||||
"description": "Texture for controlling per pixel thickness",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -1171,7 +1171,7 @@
|
||||
{
|
||||
"id": "transmissionTint",
|
||||
"displayName": " Transmission Tint",
|
||||
"description": "Color of the volume light travelling through",
|
||||
"description": "Color of the volume light traveling through",
|
||||
"type": "Color",
|
||||
"defaultValue": [ 1.0, 0.8, 0.6 ]
|
||||
},
|
||||
@@ -1246,7 +1246,7 @@
|
||||
{
|
||||
"id": "enableDetailMaskTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Enable detail mask texture",
|
||||
"description": "Enable detail blend mask",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
@@ -1265,7 +1265,7 @@
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "Detail Map UVs",
|
||||
"description": "Which UV set to use for detail map texture sampling",
|
||||
"description": "Which UV set to use for detail map sampling",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -1283,8 +1283,8 @@
|
||||
},
|
||||
{
|
||||
"id": "baseColorDetailMap",
|
||||
"displayName": " Texture Map",
|
||||
"description": "Detailed Base Color Texture map",
|
||||
"displayName": " Texture",
|
||||
"description": "Detailed Base Color Texture",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -1307,7 +1307,7 @@
|
||||
{
|
||||
"id": "enableNormals",
|
||||
"displayName": "Enable Normal",
|
||||
"description": "Enable detail normal texture to be used for fine detail normal such as scratches and small dents",
|
||||
"description": "Enable detail normal map to be used for fine detail normal such as scratches and small dents",
|
||||
"type": "Bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
@@ -1326,8 +1326,8 @@
|
||||
},
|
||||
{
|
||||
"id": "normalDetailMap",
|
||||
"displayName": " Texture Map",
|
||||
"description": "Detailed Normal Texture map",
|
||||
"displayName": " Texture",
|
||||
"description": "Detailed Normal map",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
|
||||
@@ -23,6 +23,16 @@
|
||||
"displayName": "Normal",
|
||||
"description": "Properties related to configuring surface normal."
|
||||
},
|
||||
{
|
||||
"id": "detailLayerGroup",
|
||||
"displayName": "Detail Layer",
|
||||
"description": "Properties for Fine Details Layer."
|
||||
},
|
||||
{
|
||||
"id": "detailUV",
|
||||
"displayName": "Detail Layer UV",
|
||||
"description": "Properties for modifying detail layer UV."
|
||||
},
|
||||
{
|
||||
"id": "occlusion",
|
||||
"displayName": "Occlusion",
|
||||
@@ -38,19 +48,9 @@
|
||||
"displayName": "Wrinkle Layers",
|
||||
"description": "Properties for wrinkle maps to support morph animation, using vertex color blend weights."
|
||||
},
|
||||
{
|
||||
"id": "detailLayerGroup",
|
||||
"displayName": "Detail Layer",
|
||||
"description": "Properties for Fine Details Layer."
|
||||
},
|
||||
{
|
||||
"id": "detailUV",
|
||||
"displayName": "Detail Layer UV",
|
||||
"description": "Properties for modifying detail layer UV."
|
||||
},
|
||||
{
|
||||
"id": "general",
|
||||
"displayName": "General",
|
||||
"displayName": "General Settings",
|
||||
"description": "General settings."
|
||||
}
|
||||
],
|
||||
@@ -150,7 +150,7 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"displayName": "Texture",
|
||||
"description": "Base color texture map",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
@@ -161,14 +161,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map.",
|
||||
"description": "Whether to use the texture.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Base color texture map UV set",
|
||||
"description": "Base color map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Unwrapped",
|
||||
@@ -180,7 +180,7 @@
|
||||
{
|
||||
"id": "textureBlendMode",
|
||||
"displayName": "Texture Blend Mode",
|
||||
"description": "Selects the equation to use when combining Color, Factor, and Texture Map.",
|
||||
"description": "Selects the equation to use when combining Color, Factor, and Texture.",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "Multiply", "LinearLight", "Lerp", "Overlay" ],
|
||||
"defaultValue": "Multiply",
|
||||
@@ -193,8 +193,8 @@
|
||||
"roughness": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface roughness.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface roughness.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -204,14 +204,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Roughness texture map UV set",
|
||||
"description": "Roughness map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Unwrapped",
|
||||
@@ -224,7 +224,7 @@
|
||||
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
|
||||
"id": "lowerBound",
|
||||
"displayName": "Lower Bound",
|
||||
"description": "The roughness value that corresponds to black in the texture map.",
|
||||
"description": "The roughness value that corresponds to black in the texture.",
|
||||
"type": "Float",
|
||||
"defaultValue": 0.0,
|
||||
"min": 0.0,
|
||||
@@ -238,7 +238,7 @@
|
||||
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
|
||||
"id": "upperBound",
|
||||
"displayName": "Upper Bound",
|
||||
"description": "The roughness value that corresponds to white in the texture map.",
|
||||
"description": "The roughness value that corresponds to white in the texture.",
|
||||
"type": "Float",
|
||||
"defaultValue": 1.0,
|
||||
"min": 0.0,
|
||||
@@ -279,8 +279,8 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface reflectance.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface reflectance.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -290,14 +290,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Specular reflection texture map UV set",
|
||||
"description": "Specular reflection map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Unwrapped",
|
||||
@@ -321,8 +321,8 @@
|
||||
"normal": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface normal direction.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface normal direction.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -332,14 +332,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just rely on vertex normals.",
|
||||
"description": "Whether to use the texture, or just rely on vertex normals.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Normal texture map UV set",
|
||||
"description": "Normal map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Unwrapped",
|
||||
@@ -388,7 +388,7 @@
|
||||
{
|
||||
"id": "diffuseTextureMap",
|
||||
"displayName": "Diffuse AO",
|
||||
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
|
||||
"description": "Texture for defining occlusion area for diffuse ambient lighting.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -398,14 +398,14 @@
|
||||
{
|
||||
"id": "diffuseUseTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the Diffuse AO texture map.",
|
||||
"description": "Whether to use the Diffuse AO map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "diffuseTextureMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Diffuse AO texture map UV set.",
|
||||
"description": "Diffuse AO map UV set.",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -430,7 +430,7 @@
|
||||
{
|
||||
"id": "specularTextureMap",
|
||||
"displayName": "Specular Cavity",
|
||||
"description": "Texture map for defining occlusion area for specular lighting.",
|
||||
"description": "Texture for defining occlusion area for specular lighting.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -440,14 +440,14 @@
|
||||
{
|
||||
"id": "specularUseTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the Specular Cavity texture map.",
|
||||
"description": "Whether to use the Specular Cavity map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "specularTextureMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Specular Cavity texture map UV set.",
|
||||
"description": "Specular Cavity map UV set.",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -498,7 +498,7 @@
|
||||
{
|
||||
"id": "influenceMap",
|
||||
"displayName": " Influence Map",
|
||||
"description": "Use texture map to control the strength of subsurface scattering",
|
||||
"description": "Texture for controlling the strength of subsurface scattering",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -508,7 +508,7 @@
|
||||
{
|
||||
"id": "useInfluenceMap",
|
||||
"displayName": " Use Influence Map",
|
||||
"description": "Whether to use the texture map as influence mask.",
|
||||
"description": "Whether to use the influence map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
@@ -577,7 +577,7 @@
|
||||
{
|
||||
"id": "thicknessMap",
|
||||
"displayName": " Thickness Map",
|
||||
"description": "Use a greyscale texture for per pixel thickness",
|
||||
"description": "Texture for controlling per pixel thickness",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -606,7 +606,7 @@
|
||||
{
|
||||
"id": "transmissionTint",
|
||||
"displayName": " Transmission Tint",
|
||||
"description": "Color of the volume light travelling through",
|
||||
"description": "Color of the volume light traveling through",
|
||||
"type": "Color",
|
||||
"defaultValue": [ 1.0, 0.8, 0.6 ]
|
||||
},
|
||||
@@ -792,7 +792,7 @@
|
||||
{
|
||||
"id": "enableDetailMaskTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Enable detail mask texture",
|
||||
"description": "Enable detail blend mask",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
@@ -811,7 +811,7 @@
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "Detail Map UVs",
|
||||
"description": "Which UV set to use for detail map texture sampling",
|
||||
"description": "Which UV set to use for detail map sampling",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Unwrapped",
|
||||
@@ -829,8 +829,8 @@
|
||||
},
|
||||
{
|
||||
"id": "baseColorDetailMap",
|
||||
"displayName": " Texture Map",
|
||||
"description": "Detailed Base Color Texture map",
|
||||
"displayName": " Texture",
|
||||
"description": "Detailed Base Color Texture",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -853,7 +853,7 @@
|
||||
{
|
||||
"id": "enableNormals",
|
||||
"displayName": "Enable Normal",
|
||||
"description": "Enable detail normal texture to be used for fine detail normal such as scratches and small dents",
|
||||
"description": "Enable detail normal map to be used for fine detail normal such as scratches and small dents",
|
||||
"type": "Bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
@@ -872,8 +872,8 @@
|
||||
},
|
||||
{
|
||||
"id": "normalDetailMap",
|
||||
"displayName": " Texture Map",
|
||||
"description": "Detailed Normal Texture map",
|
||||
"displayName": " Texture",
|
||||
"description": "Detailed Normal map",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
|
||||
+143
-143
File diff suppressed because it is too large
Load Diff
@@ -23,26 +23,11 @@
|
||||
"displayName": "Specular Reflectance f0",
|
||||
"description": "The constant f0 represents the specular reflectance at normal incidence (Fresnel 0 Angle). Used to adjust reflectance of non-metal surfaces."
|
||||
},
|
||||
{
|
||||
"id": "clearCoat",
|
||||
"displayName": "Clear Coat",
|
||||
"description": "Properties for configuring gloss clear coat"
|
||||
},
|
||||
{
|
||||
"id": "normal",
|
||||
"displayName": "Normal",
|
||||
"description": "Properties related to configuring surface normal."
|
||||
},
|
||||
{
|
||||
"id": "opacity",
|
||||
"displayName": "Opacity",
|
||||
"description": "Properties for configuring the materials transparency."
|
||||
},
|
||||
{
|
||||
"id": "uv",
|
||||
"displayName": "UVs",
|
||||
"description": "Properties for configuring UV transforms."
|
||||
},
|
||||
{
|
||||
"id": "occlusion",
|
||||
"displayName": "Occlusion",
|
||||
@@ -53,16 +38,31 @@
|
||||
"displayName": "Emissive",
|
||||
"description": "Properties to add light emission, independent of other lights in the scene."
|
||||
},
|
||||
{
|
||||
"id": "parallax",
|
||||
"displayName": "Parallax Mapping",
|
||||
"description": "Properties for parallax effect produced by depthmap."
|
||||
},
|
||||
{
|
||||
"id": "subsurfaceScattering",
|
||||
"displayName": "Subsurface Scattering",
|
||||
"description": "Properties for configuring subsurface scattering effects."
|
||||
},
|
||||
{
|
||||
"id": "clearCoat",
|
||||
"displayName": "Clear Coat",
|
||||
"description": "Properties for configuring gloss clear coat"
|
||||
},
|
||||
{
|
||||
"id": "parallax",
|
||||
"displayName": "Displacement",
|
||||
"description": "Properties for parallax effect produced by a height map."
|
||||
},
|
||||
{
|
||||
"id": "opacity",
|
||||
"displayName": "Opacity",
|
||||
"description": "Properties for configuring the materials transparency."
|
||||
},
|
||||
{
|
||||
"id": "uv",
|
||||
"displayName": "UVs",
|
||||
"description": "Properties for configuring UV transforms."
|
||||
},
|
||||
{
|
||||
// Note: this property group is used in the DiffuseGlobalIllumination pass, it is not read by the StandardPBR shader
|
||||
"id": "irradiance",
|
||||
@@ -71,7 +71,7 @@
|
||||
},
|
||||
{
|
||||
"id": "general",
|
||||
"displayName": "General",
|
||||
"displayName": "General Settings",
|
||||
"description": "General settings."
|
||||
}
|
||||
],
|
||||
@@ -182,7 +182,7 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"displayName": "Texture",
|
||||
"description": "Base color texture map",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
@@ -193,14 +193,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map.",
|
||||
"description": "Whether to use the texture.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Base color texture map UV set",
|
||||
"description": "Base color map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -212,7 +212,7 @@
|
||||
{
|
||||
"id": "textureBlendMode",
|
||||
"displayName": "Texture Blend Mode",
|
||||
"description": "Selects the equation to use when combining Color, Factor, and Texture Map.",
|
||||
"description": "Selects the equation to use when combining Color, Factor, and Texture.",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "Multiply", "LinearLight", "Lerp", "Overlay" ],
|
||||
"defaultValue": "Multiply",
|
||||
@@ -238,7 +238,7 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"displayName": "Texture",
|
||||
"description": "",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
@@ -249,14 +249,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Metallic texture map UV set",
|
||||
"description": "Metallic map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -269,8 +269,8 @@
|
||||
"roughness": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface roughness.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface roughness.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -280,14 +280,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Roughness texture map UV set",
|
||||
"description": "Roughness map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -300,7 +300,7 @@
|
||||
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
|
||||
"id": "lowerBound",
|
||||
"displayName": "Lower Bound",
|
||||
"description": "The roughness value that corresponds to black in the texture map.",
|
||||
"description": "The roughness value that corresponds to black in the texture.",
|
||||
"type": "Float",
|
||||
"defaultValue": 0.0,
|
||||
"min": 0.0,
|
||||
@@ -314,7 +314,7 @@
|
||||
// Note that "factor" is mutually exclusive with "lowerBound"/"upperBound". These are swapped by a lua functor.
|
||||
"id": "upperBound",
|
||||
"displayName": "Upper Bound",
|
||||
"description": "The roughness value that corresponds to white in the texture map.",
|
||||
"description": "The roughness value that corresponds to white in the texture.",
|
||||
"type": "Float",
|
||||
"defaultValue": 1.0,
|
||||
"min": 0.0,
|
||||
@@ -355,8 +355,8 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface reflectance.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface reflectance.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -366,14 +366,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Specular reflection texture map UV set",
|
||||
"description": "Specular reflection map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -418,7 +418,7 @@
|
||||
{
|
||||
"id": "influenceMap",
|
||||
"displayName": " Influence Map",
|
||||
"description": "Strength factor texture map",
|
||||
"description": "Strength factor texture",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -428,14 +428,14 @@
|
||||
{
|
||||
"id": "useInfluenceMap",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the Factor value.",
|
||||
"description": "Whether to use the texture, or just default to the Factor value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "influenceMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Strength factor texture map UV set",
|
||||
"description": "Strength factor map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -460,7 +460,7 @@
|
||||
{
|
||||
"id": "roughnessMap",
|
||||
"displayName": " Roughness Map",
|
||||
"description": "Roughness texture map",
|
||||
"description": "Texture for defining surface roughness",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -470,14 +470,14 @@
|
||||
{
|
||||
"id": "useRoughnessMap",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the texture map, or just default to the roughness value.",
|
||||
"description": "Whether to use the texture, or just default to the roughness value.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "roughnessMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Roughness texture map UV set",
|
||||
"description": "Roughness map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -519,7 +519,7 @@
|
||||
{
|
||||
"id": "normalMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Normal texture map UV set",
|
||||
"description": "Normal map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -532,8 +532,8 @@
|
||||
"normal": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface normal direction.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface normal direction.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -543,14 +543,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map, or just rely on vertex normals.",
|
||||
"description": "Whether to use the texture, or just rely on vertex normals.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Normal texture map UV set",
|
||||
"description": "Normal map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -599,7 +599,7 @@
|
||||
{
|
||||
"id": "mode",
|
||||
"displayName": "Opacity Mode",
|
||||
"description": "Opacity mode for this texture.",
|
||||
"description": "Indicates the general approach how transparency is to be applied.",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "Opaque", "Cutout", "Blended", "TintedTransparent" ],
|
||||
"defaultValue": "Opaque",
|
||||
@@ -611,7 +611,7 @@
|
||||
{
|
||||
"id": "alphaSource",
|
||||
"displayName": "Alpha Source",
|
||||
"description": "Source texture of alpha value.",
|
||||
"description": "Indicates whether to get the opacity texture from the Base Color map (Packed) or from a separate greyscale texture (Split).",
|
||||
"type": "Enum",
|
||||
"enumValues": [ "Packed", "Split", "None" ],
|
||||
"defaultValue": "Packed",
|
||||
@@ -622,8 +622,8 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining surface opacity.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining surface opacity.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -633,7 +633,7 @@
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Opacity texture map UV set",
|
||||
"description": "Opacity map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -728,7 +728,7 @@
|
||||
{
|
||||
"id": "diffuseTextureMap",
|
||||
"displayName": "Diffuse AO",
|
||||
"description": "Texture map for defining occlusion area for diffuse ambient lighting.",
|
||||
"description": "Texture for defining occlusion area for diffuse ambient lighting.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -738,14 +738,14 @@
|
||||
{
|
||||
"id": "diffuseUseTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the Diffuse AO texture map.",
|
||||
"description": "Whether to use the Diffuse AO map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "diffuseTextureMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Diffuse AO texture map UV set.",
|
||||
"description": "Diffuse AO map UV set.",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -770,7 +770,7 @@
|
||||
{
|
||||
"id": "specularTextureMap",
|
||||
"displayName": "Specular Cavity",
|
||||
"description": "Texture map for defining occlusion area for specular lighting.",
|
||||
"description": "Texture for defining occlusion area for specular lighting.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -780,14 +780,14 @@
|
||||
{
|
||||
"id": "specularUseTexture",
|
||||
"displayName": " Use Texture",
|
||||
"description": "Whether to use the Specular Cavity texture map.",
|
||||
"description": "Whether to use the Specular Cavity map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "specularTextureMapUv",
|
||||
"displayName": " UV",
|
||||
"description": "Specular Cavity texture map UV set.",
|
||||
"description": "Specular Cavity map UV set.",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -850,8 +850,8 @@
|
||||
},
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Texture Map",
|
||||
"description": "Texture map for defining emissive area.",
|
||||
"displayName": "Texture",
|
||||
"description": "Texture for defining emissive area.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -861,14 +861,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the texture map.",
|
||||
"description": "Whether to use the texture.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Emissive texture map UV set",
|
||||
"description": "Emissive map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -881,8 +881,8 @@
|
||||
"parallax": [
|
||||
{
|
||||
"id": "textureMap",
|
||||
"displayName": "Heightmap",
|
||||
"description": "Displacement heightmap to create parallax effect.",
|
||||
"displayName": "Height Map",
|
||||
"description": "Displacement height map to create parallax effect.",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -892,14 +892,14 @@
|
||||
{
|
||||
"id": "useTexture",
|
||||
"displayName": "Use Texture",
|
||||
"description": "Whether to use the heightmap.",
|
||||
"description": "Whether to use the height map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "textureMapUv",
|
||||
"displayName": "UV",
|
||||
"description": "Heightmap UV set",
|
||||
"description": "Height map UV set",
|
||||
"type": "Enum",
|
||||
"enumIsUv": true,
|
||||
"defaultValue": "Tiled",
|
||||
@@ -910,8 +910,8 @@
|
||||
},
|
||||
{
|
||||
"id": "factor",
|
||||
"displayName": "Heightmap Scale",
|
||||
"description": "The total height of the heightmap in local model units.",
|
||||
"displayName": "Height Map Scale",
|
||||
"description": "The total height of the height map in local model units.",
|
||||
"type": "Float",
|
||||
"defaultValue": 0.05,
|
||||
"min": 0.0,
|
||||
@@ -972,7 +972,7 @@
|
||||
{
|
||||
"id": "showClipping",
|
||||
"displayName": "Show Clipping",
|
||||
"description": "Highlight areas where the heightmap is clipped by the mesh surface.",
|
||||
"description": "Highlight areas where the height map is clipped by the mesh surface.",
|
||||
"type": "Bool",
|
||||
"defaultValue": false,
|
||||
"connection": {
|
||||
@@ -1009,7 +1009,7 @@
|
||||
{
|
||||
"id": "influenceMap",
|
||||
"displayName": " Influence Map",
|
||||
"description": "Use texture map to control the strength of subsurface scattering",
|
||||
"description": "Texture for controlling the strength of subsurface scattering",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -1019,7 +1019,7 @@
|
||||
{
|
||||
"id": "useInfluenceMap",
|
||||
"displayName": " Use Influence Map",
|
||||
"description": "Whether to use the texture map as influence mask.",
|
||||
"description": "Whether to use the influence map.",
|
||||
"type": "Bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
@@ -1088,7 +1088,7 @@
|
||||
{
|
||||
"id": "thicknessMap",
|
||||
"displayName": " Thickness Map",
|
||||
"description": "Use a greyscale texture for per pixel thickness",
|
||||
"description": "Texture for controlling per pixel thickness",
|
||||
"type": "Image",
|
||||
"connection": {
|
||||
"type": "ShaderInput",
|
||||
@@ -1117,7 +1117,7 @@
|
||||
{
|
||||
"id": "transmissionTint",
|
||||
"displayName": " Transmission Tint",
|
||||
"description": "Color of the volume light travelling through",
|
||||
"description": "Color of the volume light traveling through",
|
||||
"type": "Color",
|
||||
"defaultValue": [ 1.0, 0.8, 0.6 ]
|
||||
},
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Atom/Features/SrgSemantics.azsli>
|
||||
|
||||
ShaderResourceGroup RayTracingMaterialSrg : SRG_RayTracingMaterial
|
||||
{
|
||||
Sampler LinearSampler
|
||||
{
|
||||
AddressU = Wrap;
|
||||
AddressV = Wrap;
|
||||
MinFilter = Linear;
|
||||
MagFilter = Linear;
|
||||
MipFilter = Linear;
|
||||
MaxAnisotropy = 16;
|
||||
};
|
||||
|
||||
// material info structured buffer
|
||||
struct MaterialInfo
|
||||
{
|
||||
float4 m_baseColor;
|
||||
float m_metallicFactor;
|
||||
float m_roughnessFactor;
|
||||
uint m_textureFlags;
|
||||
uint m_textureStartIndex;
|
||||
};
|
||||
|
||||
// hit shaders can retrieve the MaterialInfo for a mesh hit using: RayTracingMaterialSrg::m_materialInfo[InstanceIndex()]
|
||||
StructuredBuffer<MaterialInfo> m_materialInfo;
|
||||
|
||||
// texture flag bits indicating if optional textures are present
|
||||
#define TEXTURE_FLAG_BASECOLOR 1
|
||||
#define TEXTURE_FLAG_NORMAL 2
|
||||
#define TEXTURE_FLAG_METALLIC 4
|
||||
#define TEXTURE_FLAG_ROUGHNESS 8
|
||||
|
||||
// unbounded array of Material textures
|
||||
Texture2D m_materialTextures[];
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
struct TextureData
|
||||
{
|
||||
float4 m_baseColor;
|
||||
float3 m_normal;
|
||||
float m_metallic;
|
||||
float m_roughness;
|
||||
};
|
||||
|
||||
TextureData GetHitTextureData(RayTracingMaterialSrg::MaterialInfo materialInfo, float2 uv)
|
||||
{
|
||||
TextureData textureData = (TextureData)0;
|
||||
|
||||
uint textureIndex = materialInfo.m_textureStartIndex;
|
||||
|
||||
// base color
|
||||
if (materialInfo.m_textureFlags & TEXTURE_FLAG_BASECOLOR)
|
||||
{
|
||||
textureData.m_baseColor = RayTracingMaterialSrg::m_materialTextures[textureIndex++].SampleLevel(RayTracingMaterialSrg::LinearSampler, uv, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureData.m_baseColor = materialInfo.m_baseColor;
|
||||
}
|
||||
|
||||
// normal
|
||||
if (materialInfo.m_textureFlags & TEXTURE_FLAG_NORMAL)
|
||||
{
|
||||
textureData.m_normal = RayTracingMaterialSrg::m_materialTextures[textureIndex++].SampleLevel(RayTracingMaterialSrg::LinearSampler, uv, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureData.m_normal = float3(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
// metallic
|
||||
if (materialInfo.m_textureFlags & TEXTURE_FLAG_METALLIC)
|
||||
{
|
||||
textureData.m_metallic = RayTracingMaterialSrg::m_materialTextures[textureIndex++].SampleLevel(RayTracingMaterialSrg::LinearSampler, uv, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureData.m_metallic = materialInfo.m_metallicFactor;
|
||||
}
|
||||
|
||||
// roughness
|
||||
if (materialInfo.m_textureFlags & TEXTURE_FLAG_ROUGHNESS)
|
||||
{
|
||||
textureData.m_roughness = RayTracingMaterialSrg::m_materialTextures[textureIndex++].SampleLevel(RayTracingMaterialSrg::LinearSampler, uv, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
textureData.m_roughness = materialInfo.m_roughnessFactor;
|
||||
}
|
||||
|
||||
return textureData;
|
||||
}
|
||||
|
||||
+25
-8
@@ -136,18 +136,35 @@ ShaderResourceGroup RayTracingSceneSrg : SRG_RayTracingScene
|
||||
uint m_indexOffset;
|
||||
uint m_positionOffset;
|
||||
uint m_normalOffset;
|
||||
uint m_tangentOffset;
|
||||
uint m_bitangentOffset;
|
||||
uint m_uvOffset;
|
||||
float m_padding0[2];
|
||||
|
||||
float4 m_irradianceColor;
|
||||
float3x3 m_worldInvTranspose;
|
||||
float m_padding1;
|
||||
|
||||
uint m_bufferFlags;
|
||||
uint m_bufferStartIndex;
|
||||
};
|
||||
|
||||
|
||||
// hit shaders can retrieve the MeshInfo for a mesh hit using: RayTracingSceneSrg::m_meshInfo[InstanceIndex()]
|
||||
StructuredBuffer<MeshInfo> m_meshInfo;
|
||||
|
||||
// unbounded array of Index, VertexPosition, and VertexNormal buffers
|
||||
// each mesh has three entries in this array starting at its InstanceIndex() * BUFFER_COUNT_PER_MESH
|
||||
#define BUFFER_COUNT_PER_MESH 3
|
||||
#define MESH_INDEX_BUFFER_OFFSET 0
|
||||
#define MESH_POSITION_BUFFER_OFFSET 1
|
||||
#define MESH_NORMAL_BUFFER_OFFSET 2
|
||||
|
||||
// buffer array index offsets for buffers that are always present for each mesh
|
||||
#define MESH_INDEX_BUFFER_OFFSET 0
|
||||
#define MESH_POSITION_BUFFER_OFFSET 1
|
||||
#define MESH_NORMAL_BUFFER_OFFSET 2
|
||||
#define MESH_TANGENT_BUFFER_OFFSET 3
|
||||
#define MESH_BITANGENT_BUFFER_OFFSET 4
|
||||
|
||||
// buffer flag bits indicating if optional buffers are present
|
||||
#define MESH_BUFFER_FLAG_UV 1
|
||||
|
||||
// Unbounded array of mesh stream buffers:
|
||||
// - Index, Position, Normal, Tangent, and Bitangent stream buffers are always present
|
||||
// - Optional stream buffers such as UV are indicated in the MeshInfo.m_bufferFlags field
|
||||
// - Buffers for a particular mesh start at MeshInfo.m_bufferStartIndex
|
||||
ByteAddressBuffer m_meshBuffers[];
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
// returns the normalized camera view ray into the scene for this raytracing dispatch thread
|
||||
float3 GetViewRayDirection(float4x4 viewProjectionInverseMatrix)
|
||||
{
|
||||
float2 pixel = ((float2)DispatchRaysIndex().xy + float2(0.5f, 0.5f)) / (float2)DispatchRaysDimensions();
|
||||
float2 ndc = pixel * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f);
|
||||
return normalize(mul(viewProjectionInverseMatrix, float4(ndc, 0.0f, 1.0f)).xyz);
|
||||
}
|
||||
|
||||
// returns the vertex indices for the primitive hit by the ray
|
||||
// Note: usable only in a raytracing Hit shader
|
||||
uint3 GetHitIndices(RayTracingSceneSrg::MeshInfo meshInfo)
|
||||
{
|
||||
// compute the array index of the index buffer for this mesh in the m_meshBuffers unbounded array
|
||||
uint meshIndexBufferArrayIndex = meshInfo.m_bufferStartIndex + MESH_INDEX_BUFFER_OFFSET;
|
||||
|
||||
// compute the offset into the index buffer for this primitve of the mesh
|
||||
uint offsetBytes = meshInfo.m_indexOffset + (PrimitiveIndex() * 12);
|
||||
|
||||
// load the indices for this primitive from the index buffer
|
||||
return RayTracingSceneSrg::m_meshBuffers[meshIndexBufferArrayIndex].Load3(offsetBytes);
|
||||
}
|
||||
|
||||
// returns the interpolated vertex data for the primitive hit by the ray
|
||||
// Note: usable only in a raytracing hit shader
|
||||
struct VertexData
|
||||
{
|
||||
float3 m_position;
|
||||
float3 m_normal;
|
||||
float3 m_tangent;
|
||||
float3 m_bitangent;
|
||||
float2 m_uv;
|
||||
};
|
||||
|
||||
VertexData GetHitInterpolatedVertexData(RayTracingSceneSrg::MeshInfo meshInfo, float2 builtInBarycentrics)
|
||||
{
|
||||
// retrieve the poly indices
|
||||
uint3 indices = GetHitIndices(meshInfo);
|
||||
|
||||
// compute barycentrics
|
||||
float3 barycentrics = float3((1.0f - builtInBarycentrics.x - builtInBarycentrics.y), builtInBarycentrics.x, builtInBarycentrics.y);
|
||||
|
||||
// compute the vertex data using barycentric interpolation
|
||||
VertexData vertexData = (VertexData)0;
|
||||
for (uint i = 0; i < 3; ++i)
|
||||
{
|
||||
// position
|
||||
{
|
||||
// array index of the position buffer for this mesh in the m_meshBuffers unbounded array
|
||||
uint meshVertexPositionArrayIndex = meshInfo.m_bufferStartIndex + MESH_POSITION_BUFFER_OFFSET;
|
||||
|
||||
// offset into the position buffer for this vertex
|
||||
uint positionOffset = meshInfo.m_positionOffset + (indices[i] * 12);
|
||||
|
||||
// load the position data
|
||||
vertexData.m_position += asfloat(RayTracingSceneSrg::m_meshBuffers[meshVertexPositionArrayIndex].Load3(positionOffset)) * barycentrics[i];
|
||||
}
|
||||
|
||||
// normal
|
||||
{
|
||||
// array index of the normal buffer for this mesh in the m_meshBuffers unbounded array
|
||||
uint meshVertexNormalArrayIndex = meshInfo.m_bufferStartIndex + MESH_NORMAL_BUFFER_OFFSET;
|
||||
|
||||
// offset into the normal buffer for this vertex
|
||||
uint normalOffset = meshInfo.m_normalOffset + (indices[i] * 12);
|
||||
|
||||
// load the normal data
|
||||
vertexData.m_normal += asfloat(RayTracingSceneSrg::m_meshBuffers[meshVertexNormalArrayIndex].Load3(normalOffset)) * barycentrics[i];
|
||||
}
|
||||
|
||||
// tangent
|
||||
{
|
||||
// array index of the tangent buffer for this mesh in the m_meshBuffers unbounded array
|
||||
uint meshVertexTangentArrayIndex = meshInfo.m_bufferStartIndex + MESH_TANGENT_BUFFER_OFFSET;
|
||||
|
||||
// offset into the tangent buffer for this vertex
|
||||
uint tangentOffset = meshInfo.m_tangentOffset + (indices[i] * 12);
|
||||
|
||||
// load the tangent data
|
||||
vertexData.m_tangent += asfloat(RayTracingSceneSrg::m_meshBuffers[meshVertexTangentArrayIndex].Load3(tangentOffset)) * barycentrics[i];
|
||||
}
|
||||
|
||||
// bitangent
|
||||
{
|
||||
// array index of the bitangent buffer for this mesh in the m_meshBuffers unbounded array
|
||||
uint meshVertexBitangentArrayIndex = meshInfo.m_bufferStartIndex + MESH_BITANGENT_BUFFER_OFFSET;
|
||||
|
||||
// offset into the bitangent buffer for this vertex
|
||||
uint bitangentOffset = meshInfo.m_bitangentOffset + (indices[i] * 12);
|
||||
|
||||
// load the bitangent data
|
||||
vertexData.m_bitangent += asfloat(RayTracingSceneSrg::m_meshBuffers[meshVertexBitangentArrayIndex].Load3(bitangentOffset)) * barycentrics[i];
|
||||
}
|
||||
|
||||
// optional streams begin after MESH_BITANGENT_BUFFER_OFFSET
|
||||
uint optionalBufferOffset = MESH_BITANGENT_BUFFER_OFFSET + 1;
|
||||
|
||||
// UV
|
||||
if (meshInfo.m_bufferFlags & MESH_BUFFER_FLAG_UV)
|
||||
{
|
||||
// array index of the UV buffer for this mesh in the m_meshBuffers unbounded array
|
||||
uint meshVertexUVArrayIndex = meshInfo.m_bufferStartIndex + optionalBufferOffset++;
|
||||
|
||||
// offset into the UV buffer for this vertex
|
||||
uint uvOffset = meshInfo.m_uvOffset + (indices[i] * 8);
|
||||
|
||||
// load the UV data
|
||||
vertexData.m_uv += asfloat(RayTracingSceneSrg::m_meshBuffers[meshVertexUVArrayIndex].Load2(uvOffset)) * barycentrics[i];
|
||||
}
|
||||
}
|
||||
|
||||
vertexData.m_normal = normalize(vertexData.m_normal);
|
||||
|
||||
return vertexData;
|
||||
}
|
||||
@@ -64,3 +64,8 @@ ShaderResourceGroupSemantic SRG_RayTracingScene
|
||||
{
|
||||
FrequencyId = 1;
|
||||
};
|
||||
|
||||
ShaderResourceGroupSemantic SRG_RayTracingMaterial
|
||||
{
|
||||
FrequencyId = 2;
|
||||
};
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+21
-3
@@ -44,8 +44,14 @@
|
||||
"field": "element",
|
||||
"typeName": "ShaderResourceGroupLayout",
|
||||
"typeId": "{1F92C651-9B83-4379-AB5C-5201F1B2C278}",
|
||||
"version": 6,
|
||||
"version": 7,
|
||||
"Objects": [
|
||||
{
|
||||
"field": "m_name",
|
||||
"typeName": "Name",
|
||||
"typeId": "{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"field": "m_staticSamplers",
|
||||
"typeName": "AZStd::vector",
|
||||
@@ -3338,8 +3344,14 @@
|
||||
"field": "element",
|
||||
"typeName": "ShaderResourceGroupLayout",
|
||||
"typeId": "{1F92C651-9B83-4379-AB5C-5201F1B2C278}",
|
||||
"version": 6,
|
||||
"version": 7,
|
||||
"Objects": [
|
||||
{
|
||||
"field": "m_name",
|
||||
"typeName": "Name",
|
||||
"typeId": "{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"field": "m_staticSamplers",
|
||||
"typeName": "AZStd::vector",
|
||||
@@ -6632,8 +6644,14 @@
|
||||
"field": "element",
|
||||
"typeName": "ShaderResourceGroupLayout",
|
||||
"typeId": "{1F92C651-9B83-4379-AB5C-5201F1B2C278}",
|
||||
"version": 6,
|
||||
"version": 7,
|
||||
"Objects": [
|
||||
{
|
||||
"field": "m_name",
|
||||
"typeName": "Name",
|
||||
"typeId": "{3D2B920C-9EFD-40D5-AAE0-DF131C3D4931}",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"field": "m_staticSamplers",
|
||||
"typeName": "AZStd::vector",
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:bc9981393c88c6d30a0a5a6837e6f6246a9f550042b3c4be39dd34e479b90569
|
||||
size 16793931
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="TextureSettings" version="1" type="{980132FF-C450-425D-8AE0-BD96A8486177}">
|
||||
<Class name="AZ::Uuid" field="PresetID" value="{46D9F30F-793C-4449-BCEF-12A396E61B2C}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="SizeReduceLevel" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="EngineReduce" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="EnableMipmap" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="MaintainAlphaCoverage" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="MipMapAlphaAdjustments" type="{3349AACD-BE04-50BC-9478-528BF2ACFD55}">
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="element" value="50" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="MipMapGenEval" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="ImageProcessing::MipGenType" field="MipMapGenType" value="1" type="{8524F650-1417-44DA-BBB0-C707A7A1A709}"/>
|
||||
<Class name="AZStd::map" field="PlatformSpecificOverrides" type="{74E4843B-0924-583D-8C6E-A37B09BD51FE}">
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="android" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="1" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="ios" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="1" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="mac" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="1" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}">
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#1·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{FED51EB4-F646-51FF-9646-9852CF90F353}">
|
||||
<Class name="AddressType" field="value1" value="AZStd::map({74E4843B-0924-583D-8C6E-A37B09BD51FE})::PlatformSpecificOverrides·0/AZStd::pair({CAC4E67F-D626-5452-A057-ACB57D53F549})#0·0/" version="1" type="{90752F2D-CBD3-4EE9-9CDD-447E797C8408}"/>
|
||||
<Class name="any" field="value2" type="{03924488-C7F4-4D6D-948B-ABC2D1AE2FD3}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::pair" field="element" type="{CAC4E67F-D626-5452-A057-ACB57D53F549}">
|
||||
<Class name="AZStd::string" field="value1" value="pc" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="DataPatch" field="value2" type="{BFF7A3F5-9014-4000-92C7-9B2BC7913DA9}">
|
||||
<Class name="AZ::Uuid" field="m_targetClassId" value="{980132FF-C450-425D-8AE0-BD96A8486177}" type="{E152C105-A133-4D03-BBF8-3D4B2FBA3E2A}"/>
|
||||
<Class name="unsigned int" field="m_targetClassVersion" value="1" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZStd::unordered_map" field="m_patch" type="{CEA836FC-77E0-5E46-BD0F-2E5A39D845E9}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="OverridingPlatform" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:440bcb1579d4ad667c040bda914ed3121980526a94f23879a0c482c799fd5132
|
||||
size 1310848
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cf4b22481726214c062ac27fb2d9d8a49e760a76d8fff03330ff9c5f9275a8da
|
||||
size 1966208
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8b4c99faffc34988c268613948f2004f40e9bd51de915461a4cb74edc5e8bae6
|
||||
size 134217920
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f7edea42ded8143764654f12c19e0c9b74c74afb21f435ebb59c0a4d203892a3
|
||||
size 536871104
|
||||
@@ -1,10 +0,0 @@
|
||||
The papermill 'Image base lighting' (IBL) images are modified from the following:
|
||||
|
||||
http://www.hdrlabs.com/sibl/archive.html
|
||||
'Papermill Ruins E'
|
||||
|
||||
All sIBL-sets on this page, including the images within, are licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
|
||||
|
||||
Creative Commons License: http://creativecommons.org/licenses/by-nc-sa/3.0/us/
|
||||
|
||||
Remember: Do what you want with them, but always mention where you got them from...
|
||||
@@ -89,6 +89,8 @@
|
||||
#include <ImGui/ImGuiPass.h>
|
||||
|
||||
#include <RayTracing/RayTracingAccelerationStructurePass.h>
|
||||
#include <RayTracing/RayTracingPass.h>
|
||||
#include <RayTracing/RayTracingPassData.h>
|
||||
#include <DiffuseProbeGrid/DiffuseProbeGridRayTracingPass.h>
|
||||
#include <DiffuseProbeGrid/DiffuseProbeGridBlendIrradiancePass.h>
|
||||
#include <DiffuseProbeGrid/DiffuseProbeGridBlendDistancePass.h>
|
||||
@@ -128,6 +130,7 @@ namespace AZ
|
||||
SMAAFeatureProcessor::Reflect(context);
|
||||
PostProcessFeatureProcessor::Reflect(context);
|
||||
ImGuiPassData::Reflect(context);
|
||||
RayTracingPassData::Reflect(context);
|
||||
|
||||
LightingPreset::Reflect(context);
|
||||
ModelPreset::Reflect(context);
|
||||
@@ -271,6 +274,9 @@ namespace AZ
|
||||
passSystem->AddPassCreator(Name("ReflectionScreenSpaceBlurChildPass"), &Render::ReflectionScreenSpaceBlurChildPass::Create);
|
||||
passSystem->AddPassCreator(Name("ReflectionCopyFrameBufferPass"), &Render::ReflectionCopyFrameBufferPass::Create);
|
||||
|
||||
// Add RayTracing pas
|
||||
passSystem->AddPassCreator(Name("RayTracingPass"), &Render::RayTracingPass::Create);
|
||||
|
||||
// setup handler for load pass template mappings
|
||||
m_loadTemplatesHandler = RPI::PassSystemInterface::OnReadyLoadTemplatesEvent::Handler([this]() { this->LoadPassTemplateMappings(); });
|
||||
RPI::PassSystemInterface::Get()->ConnectEvent(m_loadTemplatesHandler);
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <Atom/Utils/PpmFile.h>
|
||||
|
||||
#include <AtomCore/Serialization/Json/JsonUtils.h>
|
||||
#include <AzCore/Jobs/JobFunction.h>
|
||||
#include <AzCore/Jobs/JobCompletion.h>
|
||||
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
@@ -55,6 +57,43 @@ namespace AZ
|
||||
FrameCaptureOutputResult PngFrameCaptureOutput(
|
||||
const AZStd::string& outputFilePath, const AZ::RPI::AttachmentReadback::ReadbackResult& readbackResult)
|
||||
{
|
||||
AZStd::shared_ptr<AZStd::vector<uint8_t>> buffer = readbackResult.m_dataBuffer;
|
||||
|
||||
// convert bgra to rgba by swapping channels
|
||||
const int numChannels = AZ::RHI::GetFormatComponentCount(readbackResult.m_imageDescriptor.m_format);
|
||||
if (readbackResult.m_imageDescriptor.m_format == RHI::Format::B8G8R8A8_UNORM)
|
||||
{
|
||||
buffer = AZStd::make_shared<AZStd::vector<uint8_t>>(readbackResult.m_dataBuffer->size());
|
||||
AZStd::copy(readbackResult.m_dataBuffer->begin(), readbackResult.m_dataBuffer->end(), buffer->begin());
|
||||
|
||||
AZ::JobCompletion jobCompletion;
|
||||
const int numThreads = 8;
|
||||
const int numPixelsPerThread = buffer->size() / numChannels / numThreads;
|
||||
for (int i = 0; i < numThreads; ++i)
|
||||
{
|
||||
int startPixel = i * numPixelsPerThread;
|
||||
|
||||
AZ::Job* job = AZ::CreateJobFunction(
|
||||
[&, startPixel, numPixelsPerThread]()
|
||||
{
|
||||
for (int pixelOffset = 0; pixelOffset < numPixelsPerThread; ++pixelOffset)
|
||||
{
|
||||
if (startPixel * numChannels + numChannels < buffer->size())
|
||||
{
|
||||
AZStd::swap(
|
||||
buffer->data()[(startPixel + pixelOffset) * numChannels],
|
||||
buffer->data()[(startPixel + pixelOffset) * numChannels + 2]
|
||||
);
|
||||
}
|
||||
}
|
||||
}, true, nullptr);
|
||||
|
||||
job->SetDependent(&jobCompletion);
|
||||
job->Start();
|
||||
}
|
||||
jobCompletion.StartAndWaitForCompletion();
|
||||
}
|
||||
|
||||
using namespace OIIO;
|
||||
AZStd::unique_ptr<ImageOutput> out = ImageOutput::create(outputFilePath.c_str());
|
||||
if (out)
|
||||
@@ -62,13 +101,13 @@ namespace AZ
|
||||
ImageSpec spec(
|
||||
readbackResult.m_imageDescriptor.m_size.m_width,
|
||||
readbackResult.m_imageDescriptor.m_size.m_height,
|
||||
AZ::RHI::GetFormatComponentCount(readbackResult.m_imageDescriptor.m_format)
|
||||
numChannels
|
||||
);
|
||||
spec.attribute("png:compressionLevel", r_pngCompressionLevel);
|
||||
|
||||
if (out->open(outputFilePath.c_str(), spec))
|
||||
{
|
||||
out->write_image(TypeDesc::UINT8, readbackResult.m_dataBuffer->data());
|
||||
out->write_image(TypeDesc::UINT8, buffer->data());
|
||||
out->close();
|
||||
return FrameCaptureOutputResult{FrameCaptureResult::Success, AZStd::nullopt};
|
||||
}
|
||||
@@ -460,13 +499,23 @@ namespace AZ
|
||||
#if defined(OPEN_IMAGE_IO_ENABLED)
|
||||
else if (extension == "png")
|
||||
{
|
||||
AZStd::string folderPath;
|
||||
AzFramework::StringFunc::Path::GetFolderPath(m_outputFilePath.c_str(), folderPath);
|
||||
AZ::IO::SystemFile::CreateDir(folderPath.c_str());
|
||||
if (readbackResult.m_imageDescriptor.m_format == RHI::Format::R8G8B8A8_UNORM ||
|
||||
readbackResult.m_imageDescriptor.m_format == RHI::Format::B8G8R8A8_UNORM)
|
||||
{
|
||||
AZStd::string folderPath;
|
||||
AzFramework::StringFunc::Path::GetFolderPath(m_outputFilePath.c_str(), folderPath);
|
||||
AZ::IO::SystemFile::CreateDir(folderPath.c_str());
|
||||
|
||||
const auto frameCaptureResult = PngFrameCaptureOutput(m_outputFilePath, readbackResult);
|
||||
m_result = frameCaptureResult.m_result;
|
||||
m_latestCaptureInfo = frameCaptureResult.m_errorMessage.value_or("");
|
||||
const auto frameCaptureResult = PngFrameCaptureOutput(m_outputFilePath, readbackResult);
|
||||
m_result = frameCaptureResult.m_result;
|
||||
m_latestCaptureInfo = frameCaptureResult.m_errorMessage.value_or("");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_latestCaptureInfo = AZStd::string::format(
|
||||
"Can't save image with format %s to a png file", RHI::ToString(readbackResult.m_imageDescriptor.m_format));
|
||||
m_result = FrameCaptureResult::UnsupportedFormat;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
|
||||
@@ -710,27 +710,53 @@ namespace AZ
|
||||
uint32_t rayTracingLod = aznumeric_cast<uint32_t>(modelLods.size() - 1);
|
||||
const Data::Instance<RPI::ModelLod>& modelLod = modelLods[rayTracingLod];
|
||||
|
||||
// setup a stream layout and shader input contract for the position and normal streams
|
||||
// setup a stream layout and shader input contract for the vertex streams
|
||||
static const char* PositionSemantic = "POSITION";
|
||||
static const char* NormalSemantic = "NORMAL";
|
||||
static const RHI::Format StreamFormat = RHI::Format::R32G32B32_FLOAT;
|
||||
static const char* TangentSemantic = "TANGENT";
|
||||
static const char* BitangentSemantic = "BITANGENT";
|
||||
static const char* UVSemantic = "UV";
|
||||
static const RHI::Format PositionStreamFormat = RHI::Format::R32G32B32_FLOAT;
|
||||
static const RHI::Format NormalStreamFormat = RHI::Format::R32G32B32_FLOAT;
|
||||
static const RHI::Format TangentStreamFormat = RHI::Format::R32G32B32_FLOAT;
|
||||
static const RHI::Format BitangentStreamFormat = RHI::Format::R32G32B32_FLOAT;
|
||||
static const RHI::Format UVStreamFormat = RHI::Format::R32G32_FLOAT;
|
||||
|
||||
RHI::InputStreamLayoutBuilder layoutBuilder;
|
||||
layoutBuilder.AddBuffer()->Channel(PositionSemantic, StreamFormat);
|
||||
layoutBuilder.AddBuffer()->Channel(NormalSemantic, StreamFormat);
|
||||
layoutBuilder.AddBuffer()->Channel(PositionSemantic, PositionStreamFormat);
|
||||
layoutBuilder.AddBuffer()->Channel(NormalSemantic, NormalStreamFormat);
|
||||
layoutBuilder.AddBuffer()->Channel(UVSemantic, UVStreamFormat);
|
||||
layoutBuilder.AddBuffer()->Channel(TangentSemantic, TangentStreamFormat);
|
||||
layoutBuilder.AddBuffer()->Channel(BitangentSemantic, BitangentStreamFormat);
|
||||
RHI::InputStreamLayout inputStreamLayout = layoutBuilder.End();
|
||||
|
||||
RPI::ShaderInputContract::StreamChannelInfo positionStreamChannelInfo;
|
||||
positionStreamChannelInfo.m_semantic = RHI::ShaderSemantic(AZ::Name(PositionSemantic));
|
||||
positionStreamChannelInfo.m_componentCount = RHI::GetFormatComponentCount(StreamFormat);
|
||||
positionStreamChannelInfo.m_componentCount = RHI::GetFormatComponentCount(PositionStreamFormat);
|
||||
|
||||
RPI::ShaderInputContract::StreamChannelInfo normalStreamChannelInfo;
|
||||
normalStreamChannelInfo.m_semantic = RHI::ShaderSemantic(AZ::Name(NormalSemantic));
|
||||
normalStreamChannelInfo.m_componentCount = RHI::GetFormatComponentCount(StreamFormat);
|
||||
normalStreamChannelInfo.m_componentCount = RHI::GetFormatComponentCount(NormalStreamFormat);
|
||||
|
||||
RPI::ShaderInputContract::StreamChannelInfo tangentStreamChannelInfo;
|
||||
tangentStreamChannelInfo.m_semantic = RHI::ShaderSemantic(AZ::Name(TangentSemantic));
|
||||
tangentStreamChannelInfo.m_componentCount = RHI::GetFormatComponentCount(TangentStreamFormat);
|
||||
|
||||
RPI::ShaderInputContract::StreamChannelInfo bitangentStreamChannelInfo;
|
||||
bitangentStreamChannelInfo.m_semantic = RHI::ShaderSemantic(AZ::Name(BitangentSemantic));
|
||||
bitangentStreamChannelInfo.m_componentCount = RHI::GetFormatComponentCount(BitangentStreamFormat);
|
||||
|
||||
RPI::ShaderInputContract::StreamChannelInfo uvStreamChannelInfo;
|
||||
uvStreamChannelInfo.m_semantic = RHI::ShaderSemantic(AZ::Name(UVSemantic));
|
||||
uvStreamChannelInfo.m_componentCount = RHI::GetFormatComponentCount(UVStreamFormat);
|
||||
uvStreamChannelInfo.m_isOptional = true;
|
||||
|
||||
RPI::ShaderInputContract shaderInputContract;
|
||||
shaderInputContract.m_streamChannels.emplace_back(positionStreamChannelInfo);
|
||||
shaderInputContract.m_streamChannels.emplace_back(normalStreamChannelInfo);
|
||||
shaderInputContract.m_streamChannels.emplace_back(tangentStreamChannelInfo);
|
||||
shaderInputContract.m_streamChannels.emplace_back(bitangentStreamChannelInfo);
|
||||
shaderInputContract.m_streamChannels.emplace_back(uvStreamChannelInfo);
|
||||
|
||||
// setup the raytracing data for each sub-mesh
|
||||
const size_t meshCount = modelLod->GetMeshes().size();
|
||||
@@ -739,26 +765,6 @@ namespace AZ
|
||||
{
|
||||
const RPI::ModelLod::Mesh& mesh = modelLod->GetMeshes()[meshIndex];
|
||||
|
||||
// retrieve vertex/index buffers
|
||||
RPI::ModelLod::StreamBufferViewList streamBufferViews;
|
||||
[[maybe_unused]] bool result = modelLod->GetStreamsForMesh(inputStreamLayout, streamBufferViews, nullptr, shaderInputContract, meshIndex);
|
||||
AZ_Assert(result, "Failed to retrieve mesh stream buffer views");
|
||||
|
||||
// note that the element count is the size of the entire buffer, even though this mesh may only
|
||||
// occupy a portion of the vertex buffer. This is necessary since we are accessing it using
|
||||
// a ByteAddressBuffer in the raytracing shaders and passing the byte offset to the shader in a constant buffer.
|
||||
uint32_t vertexBufferByteCount = const_cast<RHI::Buffer*>(streamBufferViews[0].GetBuffer())->GetDescriptor().m_byteCount;
|
||||
RHI::BufferViewDescriptor vertexBufferDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, vertexBufferByteCount);
|
||||
|
||||
const RHI::IndexBufferView& indexBufferView = mesh.m_indexBufferView;
|
||||
uint32_t indexElementSize = indexBufferView.GetIndexFormat() == RHI::IndexFormat::Uint16 ? 2 : 4;
|
||||
uint32_t indexElementCount = (uint32_t)indexBufferView.GetBuffer()->GetDescriptor().m_byteCount / indexElementSize;
|
||||
RHI::BufferViewDescriptor indexBufferDescriptor;
|
||||
indexBufferDescriptor.m_elementOffset = 0;
|
||||
indexBufferDescriptor.m_elementCount = indexElementCount;
|
||||
indexBufferDescriptor.m_elementSize = indexElementSize;
|
||||
indexBufferDescriptor.m_elementFormat = indexBufferView.GetIndexFormat() == RHI::IndexFormat::Uint16 ? RHI::Format::R16_UINT : RHI::Format::R32_UINT;
|
||||
|
||||
// retrieve the material
|
||||
Data::Instance<RPI::Material> material = mesh.m_material;
|
||||
|
||||
@@ -769,31 +775,163 @@ namespace AZ
|
||||
material = materialAssignment.m_materialInstance;
|
||||
}
|
||||
|
||||
AZ::Color irradianceColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// retrieve vertex/index buffers
|
||||
RPI::ModelLod::StreamBufferViewList streamBufferViews;
|
||||
[[maybe_unused]] bool result = modelLod->GetStreamsForMesh(
|
||||
inputStreamLayout,
|
||||
streamBufferViews,
|
||||
nullptr,
|
||||
shaderInputContract,
|
||||
meshIndex,
|
||||
materialAssignment.m_matModUvOverrides,
|
||||
material->GetAsset()->GetMaterialTypeAsset()->GetUvNameMap());
|
||||
AZ_Assert(result, "Failed to retrieve mesh stream buffer views");
|
||||
|
||||
// note that the element count is the size of the entire buffer, even though this mesh may only
|
||||
// occupy a portion of the vertex buffer. This is necessary since we are accessing it using
|
||||
// a ByteAddressBuffer in the raytracing shaders and passing the byte offset to the shader in a constant buffer.
|
||||
uint32_t positionBufferByteCount = const_cast<RHI::Buffer*>(streamBufferViews[0].GetBuffer())->GetDescriptor().m_byteCount;
|
||||
RHI::BufferViewDescriptor positionBufferDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, positionBufferByteCount);
|
||||
|
||||
uint32_t normalBufferByteCount = const_cast<RHI::Buffer*>(streamBufferViews[1].GetBuffer())->GetDescriptor().m_byteCount;
|
||||
RHI::BufferViewDescriptor normalBufferDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, normalBufferByteCount);
|
||||
|
||||
uint32_t tangentBufferByteCount = const_cast<RHI::Buffer*>(streamBufferViews[2].GetBuffer())->GetDescriptor().m_byteCount;
|
||||
RHI::BufferViewDescriptor tangentBufferDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, tangentBufferByteCount);
|
||||
|
||||
uint32_t bitangentBufferByteCount = const_cast<RHI::Buffer*>(streamBufferViews[3].GetBuffer())->GetDescriptor().m_byteCount;
|
||||
RHI::BufferViewDescriptor bitangentBufferDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, bitangentBufferByteCount);
|
||||
|
||||
uint32_t uvBufferByteCount = const_cast<RHI::Buffer*>(streamBufferViews[4].GetBuffer())->GetDescriptor().m_byteCount;
|
||||
RHI::BufferViewDescriptor uvBufferDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, uvBufferByteCount);
|
||||
|
||||
const RHI::IndexBufferView& indexBufferView = mesh.m_indexBufferView;
|
||||
uint32_t indexElementSize = indexBufferView.GetIndexFormat() == RHI::IndexFormat::Uint16 ? 2 : 4;
|
||||
uint32_t indexElementCount = (uint32_t)indexBufferView.GetBuffer()->GetDescriptor().m_byteCount / indexElementSize;
|
||||
RHI::BufferViewDescriptor indexBufferDescriptor;
|
||||
indexBufferDescriptor.m_elementOffset = 0;
|
||||
indexBufferDescriptor.m_elementCount = indexElementCount;
|
||||
indexBufferDescriptor.m_elementSize = indexElementSize;
|
||||
indexBufferDescriptor.m_elementFormat = indexBufferView.GetIndexFormat() == RHI::IndexFormat::Uint16 ? RHI::Format::R16_UINT : RHI::Format::R32_UINT;
|
||||
|
||||
// set the SubMesh data to pass to the RayTracingFeatureProcessor, starting with vertex/index data
|
||||
RayTracingFeatureProcessor::SubMesh subMesh;
|
||||
subMesh.m_positionFormat = PositionStreamFormat;
|
||||
subMesh.m_positionVertexBufferView = streamBufferViews[0];
|
||||
subMesh.m_positionShaderBufferView = const_cast<RHI::Buffer*>(streamBufferViews[0].GetBuffer())->GetBufferView(positionBufferDescriptor);
|
||||
|
||||
subMesh.m_normalFormat = NormalStreamFormat;
|
||||
subMesh.m_normalVertexBufferView = streamBufferViews[1];
|
||||
subMesh.m_normalShaderBufferView = const_cast<RHI::Buffer*>(streamBufferViews[1].GetBuffer())->GetBufferView(normalBufferDescriptor);
|
||||
|
||||
subMesh.m_tangentFormat = TangentStreamFormat;
|
||||
subMesh.m_tangentVertexBufferView = streamBufferViews[2];
|
||||
subMesh.m_tangentShaderBufferView = const_cast<RHI::Buffer*>(streamBufferViews[2].GetBuffer())->GetBufferView(tangentBufferDescriptor);
|
||||
|
||||
subMesh.m_bitangentFormat = BitangentStreamFormat;
|
||||
subMesh.m_bitangentVertexBufferView = streamBufferViews[3];
|
||||
subMesh.m_bitangentShaderBufferView = const_cast<RHI::Buffer*>(streamBufferViews[3].GetBuffer())->GetBufferView(bitangentBufferDescriptor);
|
||||
|
||||
if (uvBufferByteCount > 0)
|
||||
{
|
||||
subMesh.m_bufferFlags |= RayTracingSubMeshBufferFlags::UV;
|
||||
subMesh.m_uvFormat = UVStreamFormat;
|
||||
subMesh.m_uvVertexBufferView = streamBufferViews[4];
|
||||
subMesh.m_uvShaderBufferView = const_cast<RHI::Buffer*>(streamBufferViews[4].GetBuffer())->GetBufferView(uvBufferDescriptor);
|
||||
}
|
||||
|
||||
subMesh.m_indexBufferView = mesh.m_indexBufferView;
|
||||
subMesh.m_indexShaderBufferView = const_cast<RHI::Buffer*>(mesh.m_indexBufferView.GetBuffer())->GetBufferView(indexBufferDescriptor);
|
||||
|
||||
// add material data
|
||||
if (material)
|
||||
{
|
||||
// irradiance color
|
||||
RPI::MaterialPropertyIndex propertyIndex = material->FindPropertyIndex(AZ::Name("irradiance.color"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
irradianceColor = material->GetPropertyValue<AZ::Color>(propertyIndex);
|
||||
subMesh.m_irradianceColor = material->GetPropertyValue<AZ::Color>(propertyIndex);
|
||||
}
|
||||
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("irradiance.factor"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
irradianceColor *= material->GetPropertyValue<float>(propertyIndex);
|
||||
subMesh.m_irradianceColor *= material->GetPropertyValue<float>(propertyIndex);
|
||||
}
|
||||
|
||||
// base color
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("baseColor.color"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
subMesh.m_baseColor = material->GetPropertyValue<AZ::Color>(propertyIndex);
|
||||
}
|
||||
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("baseColor.factor"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
subMesh.m_baseColor *= material->GetPropertyValue<float>(propertyIndex);
|
||||
}
|
||||
|
||||
// metallic
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("metallic.factor"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
subMesh.m_metallicFactor = material->GetPropertyValue<float>(propertyIndex);
|
||||
}
|
||||
|
||||
// roughness
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("roughness.factor"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
subMesh.m_roughnessFactor = material->GetPropertyValue<float>(propertyIndex);
|
||||
}
|
||||
|
||||
// textures
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("baseColor.textureMap"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
Data::Instance<RPI::Image> image = material->GetPropertyValue<Data::Instance<RPI::Image>>(propertyIndex);
|
||||
if (image.get())
|
||||
{
|
||||
subMesh.m_textureFlags |= RayTracingSubMeshTextureFlags::BaseColor;
|
||||
subMesh.m_baseColorImageView = image->GetImageView();
|
||||
}
|
||||
}
|
||||
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("normal.textureMap"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
Data::Instance<RPI::Image> image = material->GetPropertyValue<Data::Instance<RPI::Image>>(propertyIndex);
|
||||
if (image.get())
|
||||
{
|
||||
subMesh.m_textureFlags |= RayTracingSubMeshTextureFlags::Normal;
|
||||
subMesh.m_normalImageView = image->GetImageView();
|
||||
}
|
||||
}
|
||||
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("metallic.textureMap"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
Data::Instance<RPI::Image> image = material->GetPropertyValue<Data::Instance<RPI::Image>>(propertyIndex);
|
||||
if (image.get())
|
||||
{
|
||||
subMesh.m_textureFlags |= RayTracingSubMeshTextureFlags::Metallic;
|
||||
subMesh.m_metallicImageView = image->GetImageView();
|
||||
}
|
||||
}
|
||||
|
||||
propertyIndex = material->FindPropertyIndex(AZ::Name("roughness.textureMap"));
|
||||
if (propertyIndex.IsValid())
|
||||
{
|
||||
Data::Instance<RPI::Image> image = material->GetPropertyValue<Data::Instance<RPI::Image>>(propertyIndex);
|
||||
if (image.get())
|
||||
{
|
||||
subMesh.m_textureFlags |= RayTracingSubMeshTextureFlags::Roughness;
|
||||
subMesh.m_roughnessImageView = image->GetImageView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RayTracingFeatureProcessor::SubMesh subMesh;
|
||||
subMesh.m_vertexFormat = StreamFormat;
|
||||
subMesh.m_positionVertexBufferView = streamBufferViews[0];
|
||||
subMesh.m_positionShaderBufferView = const_cast<RHI::Buffer*>(streamBufferViews[0].GetBuffer())->GetBufferView(vertexBufferDescriptor);
|
||||
subMesh.m_normalVertexBufferView = streamBufferViews[1];
|
||||
subMesh.m_normalShaderBufferView = const_cast<RHI::Buffer*>(streamBufferViews[1].GetBuffer())->GetBufferView(vertexBufferDescriptor);
|
||||
subMesh.m_indexBufferView = mesh.m_indexBufferView;
|
||||
subMesh.m_indexShaderBufferView = const_cast<RHI::Buffer*>(mesh.m_indexBufferView.GetBuffer())->GetBufferView(indexBufferDescriptor);
|
||||
subMesh.m_irradianceColor = irradianceColor;
|
||||
subMeshes.push_back(subMesh);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -115,11 +115,11 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
// update and compile the RayTracingSceneSrg
|
||||
// update and compile the RayTracingSceneSrg and RayTracingMaterialSrg
|
||||
// Note: the timing of this update is very important, it needs to be updated after the TLAS is allocated so it can
|
||||
// be set on the RayTracingSceneSrg for this frame, and the ray tracing mesh data in the RayTracingSceneSrg must
|
||||
// exactly match the TLAS. Any mismatch in this data may result in a TDR.
|
||||
rayTracingFeatureProcessor->UpdateRayTracingSceneSrg();
|
||||
rayTracingFeatureProcessor->UpdateRayTracingSrgs();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,13 @@ namespace AZ
|
||||
AZ_Assert(rayTracingSceneSrgAsset.IsReady(), "Failed to load RayTracingSceneSrg asset");
|
||||
|
||||
m_rayTracingSceneSrg = RPI::ShaderResourceGroup::Create(rayTracingSceneSrgAsset);
|
||||
|
||||
// load the RayTracingMaterialSrg asset
|
||||
Data::Asset<RPI::ShaderResourceGroupAsset> rayTracingMaterialSrgAsset =
|
||||
RPI::AssetUtils::LoadAssetByProductPath<RPI::ShaderResourceGroupAsset>("shaderlib/atom/features/raytracing/raytracingmaterialsrg_raytracingmaterialsrg.azsrg", RPI::AssetUtils::TraceLevel::Error);
|
||||
AZ_Assert(rayTracingMaterialSrgAsset.IsReady(), "Failed to load RayTracingMaterialSrg asset");
|
||||
|
||||
m_rayTracingMaterialSrg = RPI::ShaderResourceGroup::Create(rayTracingMaterialSrgAsset);
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::SetMesh(const ObjectId objectId, const SubMeshVector& subMeshes)
|
||||
@@ -104,7 +111,7 @@ namespace AZ
|
||||
RHI::RayTracingBlasDescriptor blasDescriptor;
|
||||
blasDescriptor.Build()
|
||||
->Geometry()
|
||||
->VertexFormat(subMesh.m_vertexFormat)
|
||||
->VertexFormat(subMesh.m_positionFormat)
|
||||
->VertexBuffer(subMesh.m_positionVertexBufferView)
|
||||
->IndexBuffer(subMesh.m_indexBufferView)
|
||||
;
|
||||
@@ -124,6 +131,7 @@ namespace AZ
|
||||
m_subMeshCount += aznumeric_cast<uint32_t>(subMeshes.size());
|
||||
|
||||
m_meshInfoBufferNeedsUpdate = true;
|
||||
m_materialInfoBufferNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::RemoveMesh(const ObjectId objectId)
|
||||
@@ -142,6 +150,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
m_meshInfoBufferNeedsUpdate = true;
|
||||
m_materialInfoBufferNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::SetMeshTransform(const ObjectId objectId, const AZ::Transform transform, const AZ::Vector3 nonUniformScale)
|
||||
@@ -162,14 +171,14 @@ namespace AZ
|
||||
m_meshInfoBufferNeedsUpdate = true;
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::UpdateRayTracingSceneSrg()
|
||||
void RayTracingFeatureProcessor::UpdateRayTracingSrgs()
|
||||
{
|
||||
if (!m_tlas->GetTlasBuffer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_rayTracingSceneSrg->IsQueuedForCompile())
|
||||
if (m_rayTracingSceneSrg->IsQueuedForCompile() || m_rayTracingMaterialSrg->IsQueuedForCompile())
|
||||
{
|
||||
//[GFX TODO][ATOM-14792] AtomSampleViewer: Reset scene and feature processors before switching to sample
|
||||
return;
|
||||
@@ -178,7 +187,148 @@ namespace AZ
|
||||
// update the mesh info buffer with the latest ray tracing enabled meshes
|
||||
UpdateMeshInfoBuffer();
|
||||
|
||||
// update the material info buffer with the latest ray tracing enabled meshes
|
||||
UpdateMaterialInfoBuffer();
|
||||
|
||||
// update the RayTracingSceneSrg
|
||||
UpdateRayTracingSceneSrg();
|
||||
|
||||
// update the RayTracingMaterialSrg
|
||||
UpdateRayTracingMaterialSrg();
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::UpdateMeshInfoBuffer()
|
||||
{
|
||||
if (m_meshInfoBufferNeedsUpdate && (m_subMeshCount > 0))
|
||||
{
|
||||
TransformServiceFeatureProcessor* transformFeatureProcessor = GetParentScene()->GetFeatureProcessor<TransformServiceFeatureProcessor>();
|
||||
|
||||
AZStd::vector<MeshInfo> meshInfos;
|
||||
meshInfos.reserve(m_subMeshCount);
|
||||
|
||||
uint32_t newMeshByteCount = m_subMeshCount * sizeof(MeshInfo);
|
||||
|
||||
if (m_meshInfoBuffer == nullptr)
|
||||
{
|
||||
AZStd::string uuidString = AZ::Uuid::CreateRandom().ToString<AZStd::string>();
|
||||
|
||||
// allocate the MeshInfo structured buffer
|
||||
RPI::CommonBufferDescriptor desc;
|
||||
desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
|
||||
desc.m_bufferName = AZStd::string::format("RayTracingMeshInfo_%s", uuidString.c_str());
|
||||
desc.m_byteCount = newMeshByteCount;
|
||||
desc.m_elementSize = sizeof(MeshInfo);
|
||||
m_meshInfoBuffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
|
||||
}
|
||||
else if (m_meshInfoBuffer->GetBufferSize() < newMeshByteCount)
|
||||
{
|
||||
// resize for the new sub-mesh count
|
||||
m_meshInfoBuffer->Resize(newMeshByteCount);
|
||||
}
|
||||
|
||||
// keep track of the start index of the buffers for each mesh, this is put into the MeshInfo
|
||||
// entry for each mesh so it knows where to find the start of its buffers in the unbounded array
|
||||
uint32_t bufferStartIndex = 0;
|
||||
|
||||
for (const auto& mesh : m_meshes)
|
||||
{
|
||||
AZ::Transform meshTransform = transformFeatureProcessor->GetTransformForId(TransformServiceFeatureProcessorInterface::ObjectId(mesh.first));
|
||||
AZ::Transform noScaleTransform = meshTransform;
|
||||
noScaleTransform.ExtractUniformScale();
|
||||
AZ::Matrix3x3 rotationMatrix = Matrix3x3::CreateFromTransform(noScaleTransform);
|
||||
rotationMatrix = rotationMatrix.GetInverseFull().GetTranspose();
|
||||
|
||||
const RayTracingFeatureProcessor::SubMeshVector& subMeshes = mesh.second.m_subMeshes;
|
||||
for (const auto& subMesh : subMeshes)
|
||||
{
|
||||
MeshInfo meshInfo;
|
||||
meshInfo.m_indexOffset = subMesh.m_indexBufferView.GetByteOffset();
|
||||
meshInfo.m_positionOffset = subMesh.m_positionVertexBufferView.GetByteOffset();
|
||||
meshInfo.m_normalOffset = subMesh.m_normalVertexBufferView.GetByteOffset();
|
||||
meshInfo.m_tangentOffset = subMesh.m_tangentVertexBufferView.GetByteOffset();
|
||||
meshInfo.m_bitangentOffset = subMesh.m_bitangentVertexBufferView.GetByteOffset();
|
||||
|
||||
if (RHI::CheckBitsAll(subMesh.m_bufferFlags, RayTracingSubMeshBufferFlags::UV))
|
||||
{
|
||||
meshInfo.m_uvOffset = subMesh.m_uvVertexBufferView.GetByteOffset();
|
||||
}
|
||||
|
||||
subMesh.m_irradianceColor.StoreToFloat4(meshInfo.m_irradianceColor.data());
|
||||
rotationMatrix.StoreToRowMajorFloat9(meshInfo.m_worldInvTranspose.data());
|
||||
meshInfo.m_bufferFlags = subMesh.m_bufferFlags;
|
||||
meshInfo.m_bufferStartIndex = bufferStartIndex;
|
||||
|
||||
// add the count of buffers present in this subMesh to the start index for the next subMesh
|
||||
// note that the Index, Position, Normal, Tangent, and Bitangent buffers are always counted since they are guaranteed
|
||||
static const uint32_t RayTracingSubMeshFixedStreamCount = 5;
|
||||
bufferStartIndex += (RayTracingSubMeshFixedStreamCount + RHI::CountBitsSet(aznumeric_cast<uint32_t>(meshInfo.m_bufferFlags)));
|
||||
|
||||
meshInfos.emplace_back(meshInfo);
|
||||
}
|
||||
}
|
||||
|
||||
m_meshInfoBuffer->UpdateData(meshInfos.data(), newMeshByteCount);
|
||||
m_meshInfoBufferNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::UpdateMaterialInfoBuffer()
|
||||
{
|
||||
if (m_materialInfoBufferNeedsUpdate && (m_subMeshCount > 0))
|
||||
{
|
||||
AZStd::vector<MaterialInfo> materialInfos;
|
||||
materialInfos.reserve(m_subMeshCount);
|
||||
|
||||
uint32_t newMaterialByteCount = m_subMeshCount * sizeof(MaterialInfo);
|
||||
|
||||
if (m_materialInfoBuffer == nullptr)
|
||||
{
|
||||
AZStd::string uuidString = AZ::Uuid::CreateRandom().ToString<AZStd::string>();
|
||||
|
||||
// allocate the MaterialInfo structured buffer
|
||||
RPI::CommonBufferDescriptor desc;
|
||||
desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
|
||||
desc.m_bufferName = AZStd::string::format("RayTracingMaterialInfo_%s", uuidString.c_str());
|
||||
desc.m_byteCount = newMaterialByteCount;
|
||||
desc.m_elementSize = sizeof(MaterialInfo);
|
||||
m_materialInfoBuffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
|
||||
}
|
||||
else if (m_materialInfoBuffer->GetBufferSize() < newMaterialByteCount)
|
||||
{
|
||||
// resize for the new sub-mesh count
|
||||
m_materialInfoBuffer->Resize(newMaterialByteCount);
|
||||
}
|
||||
|
||||
// keep track of the start index of the textures for each mesh, this is put into the MaterialInfo
|
||||
// entry for each mesh so it knows where to find the start of its textures in the unbounded array
|
||||
uint32_t textureStartIndex = 0;
|
||||
|
||||
for (const auto& mesh : m_meshes)
|
||||
{
|
||||
const RayTracingFeatureProcessor::SubMeshVector& subMeshes = mesh.second.m_subMeshes;
|
||||
for (const auto& subMesh : subMeshes)
|
||||
{
|
||||
MaterialInfo materialInfo;
|
||||
subMesh.m_baseColor.StoreToFloat4(materialInfo.m_baseColor.data());
|
||||
materialInfo.m_metallicFactor = subMesh.m_metallicFactor;
|
||||
materialInfo.m_roughnessFactor = subMesh.m_roughnessFactor;
|
||||
materialInfo.m_textureFlags = subMesh.m_textureFlags;
|
||||
materialInfo.m_textureStartIndex = textureStartIndex;
|
||||
|
||||
// add the count of textures present in this subMesh to the start index for the next subMesh
|
||||
textureStartIndex += RHI::CountBitsSet(aznumeric_cast<uint32_t>(materialInfo.m_textureFlags));
|
||||
|
||||
materialInfos.emplace_back(materialInfo);
|
||||
}
|
||||
}
|
||||
|
||||
m_materialInfoBuffer->UpdateData(materialInfos.data(), newMaterialByteCount);
|
||||
m_materialInfoBufferNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::UpdateRayTracingSceneSrg()
|
||||
{
|
||||
const RHI::ShaderResourceGroupLayout* srgLayout = m_rayTracingSceneSrg->GetLayout();
|
||||
RHI::ShaderInputImageIndex imageIndex;
|
||||
RHI::ShaderInputBufferIndex bufferIndex;
|
||||
@@ -272,11 +422,18 @@ namespace AZ
|
||||
const SubMeshVector& subMeshes = mesh.second.m_subMeshes;
|
||||
for (const auto& subMesh : subMeshes)
|
||||
{
|
||||
// add the index, position, and normal buffers for this sub-mesh to the mesh buffer list, this will
|
||||
// go into the shader as an unbounded array in the Srg
|
||||
// add the stream buffers for this sub-mesh to the mesh buffer list,
|
||||
// this is sent to the shader as an unbounded array in the Srg
|
||||
meshBuffers.push_back(subMesh.m_indexShaderBufferView.get());
|
||||
meshBuffers.push_back(subMesh.m_positionShaderBufferView.get());
|
||||
meshBuffers.push_back(subMesh.m_normalShaderBufferView.get());
|
||||
meshBuffers.push_back(subMesh.m_tangentShaderBufferView.get());
|
||||
meshBuffers.push_back(subMesh.m_bitangentShaderBufferView.get());
|
||||
|
||||
if (RHI::CheckBitsAll(subMesh.m_bufferFlags, RayTracingSubMeshBufferFlags::UV))
|
||||
{
|
||||
meshBuffers.push_back(subMesh.m_uvShaderBufferView.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,58 +444,53 @@ namespace AZ
|
||||
m_rayTracingSceneSrg->Compile();
|
||||
}
|
||||
|
||||
void RayTracingFeatureProcessor::UpdateMeshInfoBuffer()
|
||||
void RayTracingFeatureProcessor::UpdateRayTracingMaterialSrg()
|
||||
{
|
||||
if (m_meshInfoBufferNeedsUpdate && (m_subMeshCount > 0))
|
||||
const RHI::ShaderResourceGroupLayout* srgLayout = m_rayTracingMaterialSrg->GetLayout();
|
||||
RHI::ShaderInputImageIndex imageIndex;
|
||||
RHI::ShaderInputBufferIndex bufferIndex;
|
||||
RHI::ShaderInputConstantIndex constantIndex;
|
||||
|
||||
bufferIndex = srgLayout->FindShaderInputBufferIndex(AZ::Name("m_materialInfo"));
|
||||
m_rayTracingMaterialSrg->SetBufferView(bufferIndex, m_materialInfoBuffer->GetBufferView());
|
||||
|
||||
if (m_subMeshCount)
|
||||
{
|
||||
TransformServiceFeatureProcessor* transformFeatureProcessor = GetParentScene()->GetFeatureProcessor<TransformServiceFeatureProcessor>();
|
||||
|
||||
AZStd::vector<MeshInfo> meshInfos;
|
||||
meshInfos.reserve(m_subMeshCount);
|
||||
|
||||
uint32_t newMeshByteCount = m_subMeshCount * sizeof(MeshInfo);
|
||||
|
||||
if (m_meshInfoBuffer == nullptr)
|
||||
{
|
||||
// allocate the MeshInfo structured buffer
|
||||
RPI::CommonBufferDescriptor desc;
|
||||
desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
|
||||
desc.m_bufferName = "RayTracingMeshInfo";
|
||||
desc.m_byteCount = newMeshByteCount;
|
||||
desc.m_elementSize = sizeof(MeshInfo);
|
||||
m_meshInfoBuffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
|
||||
}
|
||||
else if (m_meshInfoBuffer->GetBufferSize() < newMeshByteCount)
|
||||
{
|
||||
// resize for the new sub-mesh count
|
||||
m_meshInfoBuffer->Resize(newMeshByteCount);
|
||||
}
|
||||
|
||||
AZStd::vector<const RHI::ImageView*> materialTextures;
|
||||
for (const auto& mesh : m_meshes)
|
||||
{
|
||||
AZ::Transform meshTransform = transformFeatureProcessor->GetTransformForId(TransformServiceFeatureProcessorInterface::ObjectId(mesh.first));
|
||||
AZ::Transform noScaleTransform = meshTransform;
|
||||
noScaleTransform.ExtractUniformScale();
|
||||
AZ::Matrix3x3 rotationMatrix = Matrix3x3::CreateFromTransform(noScaleTransform);
|
||||
rotationMatrix = rotationMatrix.GetInverseFull().GetTranspose();
|
||||
|
||||
const RayTracingFeatureProcessor::SubMeshVector& subMeshes = mesh.second.m_subMeshes;
|
||||
const SubMeshVector& subMeshes = mesh.second.m_subMeshes;
|
||||
for (const auto& subMesh : subMeshes)
|
||||
{
|
||||
MeshInfo meshInfo;
|
||||
meshInfo.m_indexOffset = subMesh.m_indexBufferView.GetByteOffset();
|
||||
meshInfo.m_positionOffset = subMesh.m_positionVertexBufferView.GetByteOffset();
|
||||
meshInfo.m_normalOffset = subMesh.m_normalVertexBufferView.GetByteOffset();
|
||||
subMesh.m_irradianceColor.StoreToFloat4(meshInfo.m_irradianceColor.data());
|
||||
rotationMatrix.StoreToRowMajorFloat9(meshInfo.m_worldInvTranspose.data());
|
||||
// add the baseColor, normal, metallic, and roughness images for this sub-mesh to the material texture list,
|
||||
// this is sent to the shader as an unbounded array in the Srg
|
||||
if (RHI::CheckBitsAll(subMesh.m_textureFlags, RayTracingSubMeshTextureFlags::BaseColor))
|
||||
{
|
||||
materialTextures.push_back(subMesh.m_baseColorImageView.get());
|
||||
}
|
||||
|
||||
meshInfos.emplace_back(meshInfo);
|
||||
if (RHI::CheckBitsAll(subMesh.m_textureFlags, RayTracingSubMeshTextureFlags::Normal))
|
||||
{
|
||||
materialTextures.push_back(subMesh.m_normalImageView.get());
|
||||
}
|
||||
|
||||
if (RHI::CheckBitsAll(subMesh.m_textureFlags, RayTracingSubMeshTextureFlags::Metallic))
|
||||
{
|
||||
materialTextures.push_back(subMesh.m_metallicImageView.get());
|
||||
}
|
||||
|
||||
if (RHI::CheckBitsAll(subMesh.m_textureFlags, RayTracingSubMeshTextureFlags::Roughness))
|
||||
{
|
||||
materialTextures.push_back(subMesh.m_roughnessImageView.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_meshInfoBuffer->UpdateData(meshInfos.data(), newMeshByteCount);
|
||||
m_meshInfoBufferNeedsUpdate = false;
|
||||
RHI::ShaderInputImageUnboundedArrayIndex textureUnboundedArrayIndex = srgLayout->FindShaderInputImageUnboundedArrayIndex(AZ::Name("m_materialTextures"));
|
||||
m_rayTracingMaterialSrg->SetImageViewUnboundedArray(textureUnboundedArrayIndex, materialTextures);
|
||||
}
|
||||
|
||||
m_rayTracingMaterialSrg->Compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <Atom/RHI/RayTracingAccelerationStructure.h>
|
||||
#include <Atom/RHI/RayTracingBufferPools.h>
|
||||
#include <Atom/RHI/BufferView.h>
|
||||
#include <Atom/RHI/ImageView.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
|
||||
@@ -23,6 +24,28 @@ namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
static const uint32_t RayTracingGlobalSrgBindingSlot = 0;
|
||||
static const uint32_t RayTracingSceneSrgBindingSlot = 1;
|
||||
static const uint32_t RayTracingMaterialSrgBindingSlot = 2;
|
||||
|
||||
enum class RayTracingSubMeshBufferFlags : uint32_t
|
||||
{
|
||||
None = 0,
|
||||
|
||||
UV = AZ_BIT(0)
|
||||
};
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::Render::RayTracingSubMeshBufferFlags);
|
||||
|
||||
enum class RayTracingSubMeshTextureFlags : uint32_t
|
||||
{
|
||||
None = 0,
|
||||
BaseColor = AZ_BIT(0),
|
||||
Normal = AZ_BIT(1),
|
||||
Metallic = AZ_BIT(2),
|
||||
Roughness = AZ_BIT(3)
|
||||
};
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::Render::RayTracingSubMeshTextureFlags);
|
||||
|
||||
//! This feature processor manages ray tracing data for a Scene
|
||||
class RayTracingFeatureProcessor
|
||||
: public RPI::FeatureProcessor
|
||||
@@ -42,20 +65,53 @@ namespace AZ
|
||||
//! Contains data for a single sub-mesh
|
||||
struct SubMesh
|
||||
{
|
||||
// vertex/index buffer data
|
||||
RHI::Format m_vertexFormat = RHI::Format::Unknown;
|
||||
// vertex streams
|
||||
RHI::Format m_positionFormat = RHI::Format::Unknown;
|
||||
RHI::StreamBufferView m_positionVertexBufferView;
|
||||
RHI::Ptr<RHI::BufferView> m_positionShaderBufferView;
|
||||
|
||||
RHI::Format m_normalFormat = RHI::Format::Unknown;
|
||||
RHI::StreamBufferView m_normalVertexBufferView;
|
||||
RHI::Ptr<RHI::BufferView> m_normalShaderBufferView;
|
||||
|
||||
RHI::Format m_tangentFormat = RHI::Format::Unknown;
|
||||
RHI::StreamBufferView m_tangentVertexBufferView;
|
||||
RHI::Ptr<RHI::BufferView> m_tangentShaderBufferView;
|
||||
|
||||
RHI::Format m_bitangentFormat = RHI::Format::Unknown;
|
||||
RHI::StreamBufferView m_bitangentVertexBufferView;
|
||||
RHI::Ptr<RHI::BufferView> m_bitangentShaderBufferView;
|
||||
|
||||
RHI::Format m_uvFormat = RHI::Format::Unknown;
|
||||
RHI::StreamBufferView m_uvVertexBufferView;
|
||||
RHI::Ptr<RHI::BufferView> m_uvShaderBufferView;
|
||||
|
||||
// index buffer
|
||||
RHI::IndexBufferView m_indexBufferView;
|
||||
RHI::Ptr<RHI::BufferView> m_indexShaderBufferView;
|
||||
|
||||
// vertex buffer usage flags
|
||||
RayTracingSubMeshBufferFlags m_bufferFlags = RayTracingSubMeshBufferFlags::None;
|
||||
|
||||
// color of the bounced light from this sub-mesh
|
||||
AZ::Color m_irradianceColor;
|
||||
AZ::Color m_irradianceColor = AZ::Color(1.0f);
|
||||
|
||||
// ray tracing Blas
|
||||
RHI::Ptr<RHI::RayTracingBlas> m_blas;
|
||||
|
||||
// material data
|
||||
AZ::Color m_baseColor = AZ::Color(0.0f);
|
||||
float m_metallicFactor = 0.0f;
|
||||
float m_roughnessFactor = 0.0f;
|
||||
|
||||
// material texture usage flags
|
||||
RayTracingSubMeshTextureFlags m_textureFlags = RayTracingSubMeshTextureFlags::None;
|
||||
|
||||
// material textures
|
||||
RHI::Ptr<const RHI::ImageView> m_baseColorImageView;
|
||||
RHI::Ptr<const RHI::ImageView> m_normalImageView;
|
||||
RHI::Ptr<const RHI::ImageView> m_metallicImageView;
|
||||
RHI::Ptr<const RHI::ImageView> m_roughnessImageView;
|
||||
};
|
||||
using SubMeshVector = AZStd::vector<SubMesh>;
|
||||
|
||||
@@ -98,6 +154,9 @@ namespace AZ
|
||||
//! Retrieves the RayTracingSceneSrg
|
||||
Data::Instance<RPI::ShaderResourceGroup> GetRayTracingSceneSrg() const { return m_rayTracingSceneSrg; }
|
||||
|
||||
//! Retrieves the RayTracingMaterialSrg
|
||||
Data::Instance<RPI::ShaderResourceGroup> GetRayTracingMaterialSrg() const { return m_rayTracingMaterialSrg; }
|
||||
|
||||
//! Retrieves the RayTracingTlas
|
||||
const RHI::Ptr<RHI::RayTracingTlas>& GetTlas() const { return m_tlas; }
|
||||
RHI::Ptr<RHI::RayTracingTlas>& GetTlas() { return m_tlas; }
|
||||
@@ -118,14 +177,20 @@ namespace AZ
|
||||
//! Retrieves the GPU buffer containing information for all ray tracing meshes.
|
||||
const Data::Instance<RPI::Buffer> GetMeshInfoBuffer() const { return m_meshInfoBuffer; }
|
||||
|
||||
//! Updates the RayTracingSceneSrg, called after the TLAS is allocated in the RayTracingAccelerationStructurePass
|
||||
void UpdateRayTracingSceneSrg();
|
||||
//! Retrieves the GPU buffer containing information for all ray tracing materials.
|
||||
const Data::Instance<RPI::Buffer> GetMaterialInfoBuffer() const { return m_materialInfoBuffer; }
|
||||
|
||||
//! Updates the RayTracingSceneSrg and RayTracingMaterialSrg, called after the TLAS is allocated in the RayTracingAccelerationStructurePass
|
||||
void UpdateRayTracingSrgs();
|
||||
|
||||
private:
|
||||
|
||||
AZ_DISABLE_COPY_MOVE(RayTracingFeatureProcessor);
|
||||
|
||||
void UpdateMeshInfoBuffer();
|
||||
void UpdateMaterialInfoBuffer();
|
||||
void UpdateRayTracingSceneSrg();
|
||||
void UpdateRayTracingMaterialSrg();
|
||||
|
||||
// flag indicating if RayTracing is enabled, currently based on device support
|
||||
bool m_rayTracingEnabled = false;
|
||||
@@ -143,6 +208,9 @@ namespace AZ
|
||||
// ray tracing scene Srg
|
||||
Data::Instance<RPI::ShaderResourceGroup> m_rayTracingSceneSrg;
|
||||
|
||||
// ray tracing material Srg
|
||||
Data::Instance<RPI::ShaderResourceGroup> m_rayTracingMaterialSrg;
|
||||
|
||||
// current revision number of ray tracing data
|
||||
uint32_t m_revision = 0;
|
||||
|
||||
@@ -158,18 +226,43 @@ namespace AZ
|
||||
// structure for data in the m_meshInfoBuffer, shaders that use the buffer must match this type
|
||||
struct MeshInfo
|
||||
{
|
||||
uint32_t m_indexOffset;
|
||||
uint32_t m_positionOffset;
|
||||
uint32_t m_normalOffset;
|
||||
uint32_t m_indexOffset;
|
||||
uint32_t m_positionOffset;
|
||||
uint32_t m_normalOffset;
|
||||
uint32_t m_tangentOffset;
|
||||
uint32_t m_bitangentOffset;
|
||||
uint32_t m_uvOffset;
|
||||
float m_padding0[2];
|
||||
|
||||
AZStd::array<float, 4> m_irradianceColor; // float4
|
||||
AZStd::array<float, 9> m_worldInvTranspose; // float3x3
|
||||
float m_padding1;
|
||||
|
||||
RayTracingSubMeshBufferFlags m_bufferFlags = RayTracingSubMeshBufferFlags::None;
|
||||
uint32_t m_bufferStartIndex = 0;
|
||||
};
|
||||
|
||||
// buffer containing a MeshInfo for each sub-mesh
|
||||
Data::Instance<RPI::Buffer> m_meshInfoBuffer;
|
||||
|
||||
// flag indicating we need to update the mesh info GPU buffer
|
||||
// structure for data in the m_materialInfoBuffer, shaders that use the buffer must match this type
|
||||
struct MaterialInfo
|
||||
{
|
||||
AZStd::array<float, 4> m_baseColor; // float4
|
||||
float m_metallicFactor = 0.0f;
|
||||
float m_roughnessFactor = 0.0f;
|
||||
RayTracingSubMeshTextureFlags m_textureFlags = RayTracingSubMeshTextureFlags::None;
|
||||
uint32_t m_textureStartIndex = 0;
|
||||
};
|
||||
|
||||
// buffer containing a MaterialInfo for each sub-mesh
|
||||
Data::Instance<RPI::Buffer> m_materialInfoBuffer;
|
||||
|
||||
// flag indicating we need to update the meshInfo buffer
|
||||
bool m_meshInfoBufferNeedsUpdate = false;
|
||||
|
||||
// flag indicating we need to update the materialInfo buffer
|
||||
bool m_materialInfoBufferNeedsUpdate = false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <Atom/RHI/CommandList.h>
|
||||
#include <Atom/RHI/Factory.h>
|
||||
#include <Atom/RHI/FrameScheduler.h>
|
||||
#include <Atom/RHI/DispatchRaysItem.h>
|
||||
#include <Atom/RHI/RHISystemInterface.h>
|
||||
#include <Atom/RHI/PipelineState.h>
|
||||
#include <Atom/RPI.Reflect/Pass/PassTemplate.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Public/Pass/PassUtils.h>
|
||||
#include <Atom/RPI.Public/RPIUtils.h>
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <RayTracing/RayTracingPass.h>
|
||||
#include <RayTracing/RayTracingPassData.h>
|
||||
#include <RayTracing/RayTracingFeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
RPI::Ptr<RayTracingPass> RayTracingPass::Create(const RPI::PassDescriptor& descriptor)
|
||||
{
|
||||
RPI::Ptr<RayTracingPass> pass = aznew RayTracingPass(descriptor);
|
||||
return pass;
|
||||
}
|
||||
|
||||
RayTracingPass::RayTracingPass(const RPI::PassDescriptor& descriptor)
|
||||
: RenderPass(descriptor)
|
||||
, m_passDescriptor(descriptor)
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
if (device->GetFeatures().m_rayTracing == false)
|
||||
{
|
||||
// raytracing is not supported on this platform
|
||||
SetEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
RayTracingPass::~RayTracingPass()
|
||||
{
|
||||
RPI::ShaderReloadNotificationBus::MultiHandler::BusDisconnect();
|
||||
}
|
||||
|
||||
void RayTracingPass::Init()
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
|
||||
m_passData = RPI::PassUtils::GetPassData<RayTracingPassData>(m_passDescriptor);
|
||||
if (m_passData == nullptr)
|
||||
{
|
||||
AZ_Error("PassSystem", false, "RayTracingPass [%s]: Invalid RayTracingPassData", GetPathName().GetCStr());
|
||||
return;
|
||||
}
|
||||
|
||||
// ray generation shader
|
||||
m_rayGenerationShader = LoadShader(m_passData->m_rayGenerationShaderAssetReference);
|
||||
if (m_rayGenerationShader == nullptr)
|
||||
{
|
||||
AZ_Error("PassSystem", false, "RayTracingPass [%s]: Failed to load RayGeneration shader [%s]", GetPathName().GetCStr(), m_passData->m_rayGenerationShaderAssetReference.m_filePath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
auto shaderVariant = m_rayGenerationShader->GetVariant(RPI::ShaderAsset::RootShaderVariantStableId);
|
||||
RHI::PipelineStateDescriptorForRayTracing rayGenerationShaderDescriptor;
|
||||
shaderVariant.ConfigurePipelineState(rayGenerationShaderDescriptor);
|
||||
|
||||
// closest hit shader
|
||||
m_closestHitShader = LoadShader(m_passData->m_closestHitShaderAssetReference);
|
||||
if (m_closestHitShader == nullptr)
|
||||
{
|
||||
AZ_Error("PassSystem", false, "RayTracingPass [%s]: Failed to load ClosestHit shader [%s]", GetPathName().GetCStr(), m_passData->m_closestHitShaderAssetReference.m_filePath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
shaderVariant = m_closestHitShader->GetVariant(RPI::ShaderAsset::RootShaderVariantStableId);
|
||||
RHI::PipelineStateDescriptorForRayTracing closestHitShaderDescriptor;
|
||||
shaderVariant.ConfigurePipelineState(closestHitShaderDescriptor);
|
||||
|
||||
// miss shader
|
||||
m_missShader = LoadShader(m_passData->m_missShaderAssetReference);
|
||||
if (m_missShader == nullptr)
|
||||
{
|
||||
AZ_Error("PassSystem", false, "RayTracingPass [%s]: Failed to load Miss shader [%s]", GetPathName().GetCStr(), m_passData->m_missShaderAssetReference.m_filePath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
shaderVariant = m_missShader->GetVariant(RPI::ShaderAsset::RootShaderVariantStableId);
|
||||
RHI::PipelineStateDescriptorForRayTracing missShaderDescriptor;
|
||||
shaderVariant.ConfigurePipelineState(missShaderDescriptor);
|
||||
|
||||
// retrieve global pipeline state
|
||||
m_globalPipelineState = m_rayGenerationShader->AcquirePipelineState(rayGenerationShaderDescriptor);
|
||||
AZ_Assert(m_globalPipelineState, "Failed to acquire ray tracing global pipeline state");
|
||||
|
||||
// create global srg
|
||||
Data::Asset<RPI::ShaderResourceGroupAsset> globalSrgAsset = m_rayGenerationShader->FindShaderResourceGroupAsset(RayTracingGlobalSrgBindingSlot);
|
||||
AZ_Error("PassSystem", globalSrgAsset.GetId().IsValid(), "RayTracingPass [%s] Failed to find RayTracingGlobalSrg asset", GetPathName().GetCStr());
|
||||
AZ_Error("PassSystem", globalSrgAsset.IsReady(), "RayTracingPass [%s] asset is not loaded for shader", GetPathName().GetCStr());
|
||||
|
||||
m_shaderResourceGroup = RPI::ShaderResourceGroup::Create(globalSrgAsset);
|
||||
AZ_Assert(m_shaderResourceGroup, "RayTracingPass [%s]: Failed to create RayTracingGlobalSrg", GetPathName().GetCStr());
|
||||
RPI::PassUtils::BindDataMappingsToSrg(m_passDescriptor, m_shaderResourceGroup.get());
|
||||
|
||||
// check to see if the shader requires the View and RayTracingMaterial Srgs
|
||||
Data::Asset<RPI::ShaderResourceGroupAsset> viewSrgAsset = m_rayGenerationShader->FindShaderResourceGroupAsset(RPI::SrgBindingSlot::View);
|
||||
m_requiresViewSrg = viewSrgAsset.GetId().IsValid();
|
||||
|
||||
Data::Asset<RPI::ShaderResourceGroupAsset> rayTracingMaterialSrgAsset = m_rayGenerationShader->FindShaderResourceGroupAsset(RayTracingMaterialSrgBindingSlot);
|
||||
m_requiresRayTracingMaterialSrg = rayTracingMaterialSrgAsset.GetId().IsValid();
|
||||
|
||||
// build the ray tracing pipeline state descriptor
|
||||
RHI::RayTracingPipelineStateDescriptor descriptor;
|
||||
descriptor.Build()
|
||||
->PipelineState(m_globalPipelineState.get())
|
||||
->MaxPayloadSize(m_passData->m_maxPayloadSize)
|
||||
->MaxAttributeSize(m_passData->m_maxAttributeSize)
|
||||
->MaxRecursionDepth(m_passData->m_maxRecursionDepth)
|
||||
->ShaderLibrary(rayGenerationShaderDescriptor)
|
||||
->RayGenerationShaderName(AZ::Name(m_passData->m_rayGenerationShaderName.c_str()))
|
||||
->ShaderLibrary(missShaderDescriptor)
|
||||
->MissShaderName(AZ::Name(m_passData->m_missShaderName.c_str()))
|
||||
->ShaderLibrary(closestHitShaderDescriptor)
|
||||
->ClosestHitShaderName(AZ::Name(m_passData->m_closestHitShaderName.c_str()))
|
||||
->HitGroup(AZ::Name("HitGroup"))
|
||||
->ClosestHitShaderName(AZ::Name(m_passData->m_closestHitShaderName.c_str()));
|
||||
|
||||
// create the ray tracing pipeline state object
|
||||
m_rayTracingPipelineState = RHI::Factory::Get().CreateRayTracingPipelineState();
|
||||
m_rayTracingPipelineState->Init(*device.get(), &descriptor);
|
||||
|
||||
// make sure the shader table rebuilds if we're hotreloading
|
||||
m_rayTracingRevision = 0;
|
||||
|
||||
RPI::ShaderReloadNotificationBus::MultiHandler::BusDisconnect();
|
||||
RPI::ShaderReloadNotificationBus::MultiHandler::BusConnect(m_passData->m_rayGenerationShaderAssetReference.m_assetId);
|
||||
RPI::ShaderReloadNotificationBus::MultiHandler::BusConnect(m_passData->m_closestHitShaderAssetReference.m_assetId);
|
||||
RPI::ShaderReloadNotificationBus::MultiHandler::BusConnect(m_passData->m_missShaderAssetReference.m_assetId);
|
||||
}
|
||||
|
||||
Data::Instance<RPI::Shader> RayTracingPass::LoadShader(const RPI::AssetReference& shaderAssetReference)
|
||||
{
|
||||
Data::Asset<RPI::ShaderAsset> shaderAsset;
|
||||
if (shaderAssetReference.m_assetId.IsValid())
|
||||
{
|
||||
shaderAsset = RPI::FindShaderAsset(shaderAssetReference.m_assetId, shaderAssetReference.m_filePath);
|
||||
}
|
||||
|
||||
if (!shaderAsset.GetId().IsValid())
|
||||
{
|
||||
AZ_Error("PassSystem", false, "RayTracingPass [%s]: Failed to load shader asset [%s]", GetPathName().GetCStr(), shaderAssetReference.m_filePath.data());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return RPI::Shader::FindOrCreate(shaderAsset);
|
||||
}
|
||||
|
||||
void RayTracingPass::FrameBeginInternal(FramePrepareParams params)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
RayTracingFeatureProcessor* rayTracingFeatureProcessor = scene->GetFeatureProcessor<RayTracingFeatureProcessor>();
|
||||
if (!rayTracingFeatureProcessor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_rayTracingShaderTable)
|
||||
{
|
||||
RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
|
||||
RHI::RayTracingBufferPools& rayTracingBufferPools = rayTracingFeatureProcessor->GetBufferPools();
|
||||
|
||||
m_rayTracingShaderTable = RHI::Factory::Get().CreateRayTracingShaderTable();
|
||||
m_rayTracingShaderTable->Init(*device.get(), rayTracingBufferPools);
|
||||
}
|
||||
|
||||
RPI::RenderPass::FrameBeginInternal(params);
|
||||
}
|
||||
|
||||
void RayTracingPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
RayTracingFeatureProcessor* rayTracingFeatureProcessor = scene->GetFeatureProcessor<RayTracingFeatureProcessor>();
|
||||
AZ_Assert(rayTracingFeatureProcessor, "RayTracingPass requires the RayTracingFeatureProcessor");
|
||||
|
||||
RPI::RenderPass::SetupFrameGraphDependencies(frameGraph);
|
||||
frameGraph.SetEstimatedItemCount(1);
|
||||
|
||||
// TLAS
|
||||
{
|
||||
const RHI::Ptr<RHI::Buffer>& rayTracingTlasBuffer = rayTracingFeatureProcessor->GetTlas()->GetTlasBuffer();
|
||||
if (rayTracingTlasBuffer)
|
||||
{
|
||||
AZ::RHI::AttachmentId tlasAttachmentId = rayTracingFeatureProcessor->GetTlasAttachmentId();
|
||||
if (frameGraph.GetAttachmentDatabase().IsAttachmentValid(tlasAttachmentId) == false)
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportBuffer(tlasAttachmentId, rayTracingTlasBuffer);
|
||||
AZ_Assert(result == RHI::ResultCode::Success, "Failed to import ray tracing TLAS buffer with error %d", result);
|
||||
}
|
||||
|
||||
uint32_t tlasBufferByteCount = aznumeric_cast<uint32_t>(rayTracingFeatureProcessor->GetTlas()->GetTlasBuffer()->GetDescriptor().m_byteCount);
|
||||
RHI::BufferViewDescriptor tlasBufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, tlasBufferByteCount);
|
||||
|
||||
RHI::BufferScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = tlasAttachmentId;
|
||||
desc.m_bufferViewDescriptor = tlasBufferViewDescriptor;
|
||||
desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
|
||||
|
||||
frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RayTracingPass::CompileResources(const RHI::FrameGraphCompileContext& context)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
RayTracingFeatureProcessor* rayTracingFeatureProcessor = scene->GetFeatureProcessor<RayTracingFeatureProcessor>();
|
||||
AZ_Assert(rayTracingFeatureProcessor, "RayTracingPass requires the RayTracingFeatureProcessor");
|
||||
|
||||
if (m_shaderResourceGroup != nullptr)
|
||||
{
|
||||
BindPassSrg(context, m_shaderResourceGroup);
|
||||
m_shaderResourceGroup->Compile();
|
||||
}
|
||||
|
||||
uint32_t rayTracingRevision = rayTracingFeatureProcessor->GetRevision();
|
||||
if (m_rayTracingRevision != rayTracingRevision)
|
||||
{
|
||||
// scene changed, need to rebuild the shader table
|
||||
m_rayTracingRevision = rayTracingRevision;
|
||||
|
||||
AZStd::shared_ptr<RHI::RayTracingShaderTableDescriptor> descriptor = AZStd::make_shared<RHI::RayTracingShaderTableDescriptor>();
|
||||
|
||||
if (rayTracingFeatureProcessor->GetSubMeshCount())
|
||||
{
|
||||
// build the ray tracing shader table descriptor
|
||||
RHI::RayTracingShaderTableDescriptor* descriptorBuild = descriptor->Build(AZ::Name("RayTracingShaderTable"), m_rayTracingPipelineState)
|
||||
->RayGenerationRecord(AZ::Name(m_passData->m_rayGenerationShaderName.c_str()))
|
||||
->MissRecord(AZ::Name(m_passData->m_missShaderName.c_str()));
|
||||
|
||||
// add a hit group for each mesh to the shader table
|
||||
for (uint32_t i = 0; i < rayTracingFeatureProcessor->GetSubMeshCount(); ++i)
|
||||
{
|
||||
descriptorBuild->HitGroupRecord(AZ::Name("HitGroup"));
|
||||
}
|
||||
}
|
||||
|
||||
m_rayTracingShaderTable->Build(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
void RayTracingPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
|
||||
{
|
||||
RPI::Scene* scene = m_pipeline->GetScene();
|
||||
RayTracingFeatureProcessor* rayTracingFeatureProcessor = scene->GetFeatureProcessor<RayTracingFeatureProcessor>();
|
||||
AZ_Assert(rayTracingFeatureProcessor, "RayTracingPass requires the RayTracingFeatureProcessor");
|
||||
|
||||
if (!rayTracingFeatureProcessor ||
|
||||
!rayTracingFeatureProcessor->GetTlas()->GetTlasBuffer() ||
|
||||
!rayTracingFeatureProcessor->GetSubMeshCount() ||
|
||||
!m_rayTracingShaderTable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RHI::DispatchRaysItem dispatchRaysItem;
|
||||
|
||||
// calculate thread counts if this is a full screen raytracing pass
|
||||
if (m_passData->m_makeFullscreenPass)
|
||||
{
|
||||
RPI::PassAttachment* outputAttachment = nullptr;
|
||||
|
||||
if (GetOutputCount() > 0)
|
||||
{
|
||||
outputAttachment = GetOutputBinding(0).m_attachment.get();
|
||||
}
|
||||
else if (GetInputOutputCount() > 0)
|
||||
{
|
||||
outputAttachment = GetInputOutputBinding(0).m_attachment.get();
|
||||
}
|
||||
|
||||
AZ_Assert(outputAttachment != nullptr, "[RayTracingPass '%s']: A fullscreen RayTracing pass must have a valid output or input/output.", GetPathName().GetCStr());
|
||||
AZ_Assert(outputAttachment->GetAttachmentType() == RHI::AttachmentType::Image, "[RayTracingPass '%s']: The output of a fullscreen RayTracing pass must be an image.", GetPathName().GetCStr());
|
||||
|
||||
RHI::Size imageSize = outputAttachment->m_descriptor.m_image.m_size;
|
||||
|
||||
dispatchRaysItem.m_width = imageSize.m_width;
|
||||
dispatchRaysItem.m_height = imageSize.m_height;
|
||||
dispatchRaysItem.m_depth = imageSize.m_depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatchRaysItem.m_width = m_passData->m_threadCountX;
|
||||
dispatchRaysItem.m_height = m_passData->m_threadCountY;
|
||||
dispatchRaysItem.m_depth = m_passData->m_threadCountZ;
|
||||
}
|
||||
|
||||
// bind RayTracingGlobal, RayTracingScene, and View Srgs
|
||||
// [GFX TODO][ATOM-15610] Add RenderPass::SetSrgsForRayTracingDispatch
|
||||
AZStd::vector<RHI::ShaderResourceGroup*> shaderResourceGroups =
|
||||
{
|
||||
m_shaderResourceGroup->GetRHIShaderResourceGroup(),
|
||||
rayTracingFeatureProcessor->GetRayTracingSceneSrg()->GetRHIShaderResourceGroup()
|
||||
};
|
||||
|
||||
if (m_requiresViewSrg)
|
||||
{
|
||||
const AZStd::vector<RPI::ViewPtr>& views = m_pipeline->GetViews(m_passData->m_pipelineViewTag);
|
||||
if (views.size() > 0)
|
||||
{
|
||||
shaderResourceGroups.push_back(views[0]->GetRHIShaderResourceGroup());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_requiresRayTracingMaterialSrg)
|
||||
{
|
||||
shaderResourceGroups.push_back(rayTracingFeatureProcessor->GetRayTracingMaterialSrg()->GetRHIShaderResourceGroup());
|
||||
}
|
||||
|
||||
dispatchRaysItem.m_shaderResourceGroupCount = aznumeric_cast<uint32_t>(shaderResourceGroups.size());
|
||||
dispatchRaysItem.m_shaderResourceGroups = shaderResourceGroups.data();
|
||||
dispatchRaysItem.m_rayTracingPipelineState = m_rayTracingPipelineState.get();
|
||||
dispatchRaysItem.m_rayTracingShaderTable = m_rayTracingShaderTable.get();
|
||||
dispatchRaysItem.m_globalPipelineState = m_globalPipelineState.get();
|
||||
|
||||
// submit the DispatchRays item
|
||||
context.GetCommandList()->Submit(dispatchRaysItem);
|
||||
}
|
||||
|
||||
void RayTracingPass::OnShaderReinitialized([[maybe_unused]] const RPI::Shader& shader)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void RayTracingPass::OnShaderAssetReinitialized([[maybe_unused]] const Data::Asset<RPI::ShaderAsset>& shaderAsset)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void RayTracingPass::OnShaderVariantReinitialized([[maybe_unused]] const RPI::Shader& shader, [[maybe_unused]] const RPI::ShaderVariantId& shaderVariantId, [[maybe_unused]] RPI::ShaderVariantStableId shaderVariantStableId)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <Atom/RHI/RayTracingPipelineState.h>
|
||||
#include <Atom/RHI/RayTracingShaderTable.h>
|
||||
#include <Atom/RPI.Public/Pass/RenderPass.h>
|
||||
#include <Atom/RPI.Public/Shader/Shader.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderReloadNotificationBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
struct RayTracingPassData;
|
||||
|
||||
//! This pass executes a raytracing shader as specified in the PassData.
|
||||
class RayTracingPass
|
||||
: public RPI::RenderPass
|
||||
, private RPI::ShaderReloadNotificationBus::MultiHandler
|
||||
{
|
||||
AZ_RPI_PASS(RayTracingPass);
|
||||
|
||||
public:
|
||||
AZ_RTTI(RayTracingPass, "{7A68A36E-956A-4258-93FE-38686042C4D9}", RPI::RenderPass);
|
||||
AZ_CLASS_ALLOCATOR(RayTracingPass, SystemAllocator, 0);
|
||||
virtual ~RayTracingPass();
|
||||
|
||||
//! Creates a RayTracingPass
|
||||
static RPI::Ptr<RayTracingPass> Create(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
protected:
|
||||
RayTracingPass(const RPI::PassDescriptor& descriptor);
|
||||
|
||||
// Pass overrides
|
||||
void FrameBeginInternal(FramePrepareParams params) override;
|
||||
|
||||
// Scope producer functions
|
||||
void SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph) override;
|
||||
void CompileResources(const RHI::FrameGraphCompileContext& context) override;
|
||||
void BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context) override;
|
||||
|
||||
// ShaderReloadNotificationBus::Handler overrides
|
||||
void OnShaderReinitialized(const RPI::Shader& shader) override;
|
||||
void OnShaderAssetReinitialized(const Data::Asset<RPI::ShaderAsset>& shaderAsset) override;
|
||||
void OnShaderVariantReinitialized(const RPI::Shader& shader, const RPI::ShaderVariantId& shaderVariantId, RPI::ShaderVariantStableId shaderVariantStableId) override;
|
||||
|
||||
// load the raytracing shaders and setup pipeline states
|
||||
void Init();
|
||||
|
||||
// helper for loading a shader from a shader asset reference
|
||||
Data::Instance<RPI::Shader> LoadShader(const RPI::AssetReference& shaderAssetReference);
|
||||
|
||||
// pass data
|
||||
RPI::PassDescriptor m_passDescriptor;
|
||||
const RayTracingPassData* m_passData = nullptr;
|
||||
|
||||
// revision number of the ray tracing TLAS when the shader table was built
|
||||
uint32_t m_rayTracingRevision = 0;
|
||||
|
||||
// raytracing shaders, pipeline states, and shader table
|
||||
Data::Instance<RPI::Shader> m_rayGenerationShader;
|
||||
Data::Instance<RPI::Shader> m_missShader;
|
||||
Data::Instance<RPI::Shader> m_closestHitShader;
|
||||
RHI::Ptr<RHI::RayTracingPipelineState> m_rayTracingPipelineState;
|
||||
RHI::ConstPtr<RHI::PipelineState> m_globalPipelineState;
|
||||
RHI::Ptr<RHI::RayTracingShaderTable> m_rayTracingShaderTable;
|
||||
bool m_requiresViewSrg = false;
|
||||
bool m_requiresRayTracingMaterialSrg = false;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Atom/RPI.Reflect/Asset/AssetReference.h>
|
||||
#include <Atom/RPI.Reflect/Pass/RenderPassData.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! Custom data for the RayTracingPass, specified in the PassRequest.
|
||||
struct RayTracingPassData
|
||||
: public RPI::RenderPassData
|
||||
{
|
||||
AZ_RTTI(RayTracingPassData, "{26C2E2FD-D30A-4142-82A3-0167BC94B3EE}", RPI::RenderPassData);
|
||||
AZ_CLASS_ALLOCATOR(RayTracingPassData, SystemAllocator, 0);
|
||||
|
||||
RayTracingPassData() = default;
|
||||
virtual ~RayTracingPassData() = default;
|
||||
|
||||
static void Reflect(ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<RayTracingPassData, RenderPassData>()
|
||||
->Version(1)
|
||||
->Field("RayGenerationShaderAsset", &RayTracingPassData::m_rayGenerationShaderAssetReference)
|
||||
->Field("RayGenerationShaderName", &RayTracingPassData::m_rayGenerationShaderName)
|
||||
->Field("ClosestHitShaderAsset", &RayTracingPassData::m_closestHitShaderAssetReference)
|
||||
->Field("ClosestHitShaderName", &RayTracingPassData::m_closestHitShaderName)
|
||||
->Field("MissShaderAsset", &RayTracingPassData::m_missShaderAssetReference)
|
||||
->Field("MissShaderName", &RayTracingPassData::m_missShaderName)
|
||||
->Field("MaxPayloadSize", &RayTracingPassData::m_maxPayloadSize)
|
||||
->Field("MaxAttributeSize", &RayTracingPassData::m_maxAttributeSize)
|
||||
->Field("MaxRecursionDepth", &RayTracingPassData::m_maxRecursionDepth)
|
||||
->Field("Thread Count X", &RayTracingPassData::m_threadCountX)
|
||||
->Field("Thread Count Y", &RayTracingPassData::m_threadCountY)
|
||||
->Field("Thread Count Z", &RayTracingPassData::m_threadCountZ)
|
||||
->Field("Make Fullscreen Pass", &RayTracingPassData::m_makeFullscreenPass)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
RPI::AssetReference m_rayGenerationShaderAssetReference;
|
||||
AZStd::string m_rayGenerationShaderName;
|
||||
RPI::AssetReference m_closestHitShaderAssetReference;
|
||||
AZStd::string m_closestHitShaderName;
|
||||
RPI::AssetReference m_missShaderAssetReference;
|
||||
AZStd::string m_missShaderName;
|
||||
|
||||
uint32_t m_maxPayloadSize = 64;
|
||||
uint32_t m_maxAttributeSize = 32;
|
||||
uint32_t m_maxRecursionDepth = 1;
|
||||
|
||||
uint32_t m_threadCountX = 1;
|
||||
uint32_t m_threadCountY = 1;
|
||||
uint32_t m_threadCountZ = 1;
|
||||
|
||||
bool m_makeFullscreenPass = false;
|
||||
};
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -250,6 +250,9 @@ set(FILES
|
||||
Source/RayTracing/RayTracingFeatureProcessor.cpp
|
||||
Source/RayTracing/RayTracingAccelerationStructurePass.cpp
|
||||
Source/RayTracing/RayTracingAccelerationStructurePass.h
|
||||
Source/RayTracing/RayTracingPass.cpp
|
||||
Source/RayTracing/RayTracingPass.h
|
||||
Source/RayTracing/RayTracingPassData.h
|
||||
Source/ReflectionProbe/ReflectionProbeFeatureProcessor.cpp
|
||||
Source/ReflectionProbe/ReflectionProbe.cpp
|
||||
Source/ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.cpp
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace AZ
|
||||
//! In the source data, properties and UV names are loaded separately.
|
||||
//! However, treating UV names as a special property group can greatly simplify the editor code.
|
||||
//! See MaterialInspector::AddUvNamesGroup() for more details.
|
||||
static constexpr const char UvGroupName[] = "UvNames";
|
||||
static constexpr const char UvGroupName[] = "uvSets";
|
||||
|
||||
class MaterialAsset;
|
||||
|
||||
|
||||
@@ -59,7 +59,10 @@ namespace AZ
|
||||
static constexpr uint32_t Draw = 0;
|
||||
static constexpr uint32_t Object = 1;
|
||||
static constexpr uint32_t Material = 2;
|
||||
static constexpr uint32_t SubPass = 3;
|
||||
static constexpr uint32_t Pass = 4;
|
||||
static constexpr uint32_t View = 5;
|
||||
static constexpr uint32_t Scene = 6;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+15
-4
@@ -15,6 +15,7 @@
|
||||
#include <AtomToolsFramework/Viewport/ModularViewportCameraController.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
@@ -24,6 +25,11 @@
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
AZ_CVAR(
|
||||
AZ::Color, ed_cameraSystemOrbitPointColor, AZ::Color::CreateFromRgba(255, 255, 255, 255), nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitPointSize, 0.5f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
// debug
|
||||
void DrawPreviewAxis(AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, const float axisLength)
|
||||
{
|
||||
@@ -73,7 +79,8 @@ namespace AtomToolsFramework
|
||||
|
||||
if (auto viewportContext = RetrieveViewportContext(GetViewportId()))
|
||||
{
|
||||
auto handleCameraChange = [this, viewportContext](const AZ::Matrix4x4&) {
|
||||
auto handleCameraChange = [this, viewportContext](const AZ::Matrix4x4&)
|
||||
{
|
||||
if (!m_updatingTransform)
|
||||
{
|
||||
UpdateCameraFromTransform(m_targetCamera, viewportContext->GetCameraTransform());
|
||||
@@ -137,7 +144,10 @@ namespace AtomToolsFramework
|
||||
}
|
||||
else if (m_cameraMode == CameraMode::Animation)
|
||||
{
|
||||
const auto smootherStepFn = [](const float t) { return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f); };
|
||||
const auto smootherStepFn = [](const float t)
|
||||
{
|
||||
return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);
|
||||
};
|
||||
const float transitionT = smootherStepFn(m_animationT);
|
||||
|
||||
const AZ::Transform current = AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
@@ -169,8 +179,9 @@ namespace AtomToolsFramework
|
||||
{
|
||||
if (const float alpha = AZStd::min(-m_camera.m_lookDist / 5.0f, 1.0f); alpha > AZ::Constants::FloatEpsilon)
|
||||
{
|
||||
debugDisplay.SetColor(1.0f, 1.0f, 1.0f, alpha);
|
||||
debugDisplay.DrawWireSphere(m_camera.m_lookAt, 0.5f);
|
||||
const AZ::Color orbitPointColor = ed_cameraSystemOrbitPointColor;
|
||||
debugDisplay.SetColor(orbitPointColor.GetR(), orbitPointColor.GetG(), orbitPointColor.GetB(), alpha);
|
||||
debugDisplay.DrawWireSphere(m_camera.m_lookAt, ed_cameraSystemOrbitPointSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ namespace AZ
|
||||
namespace MaterialEditor
|
||||
{
|
||||
//! UVs are processed in a property group but will be handled differently.
|
||||
static constexpr const char UvGroupName[] = "UvNames";
|
||||
static constexpr const char UvGroupName[] = "uvSets";
|
||||
|
||||
class MaterialDocumentRequests
|
||||
: public AZ::EBusTraits
|
||||
|
||||
@@ -819,10 +819,10 @@ namespace MaterialEditor
|
||||
// is implemented.
|
||||
AtomToolsFramework::DynamicPropertyConfig propertyConfig;
|
||||
propertyConfig.m_dataType = AtomToolsFramework::DynamicPropertyType::Asset;
|
||||
propertyConfig.m_id = "details.materialType";
|
||||
propertyConfig.m_id = "overview.materialType";
|
||||
propertyConfig.m_nameId = "materialType";
|
||||
propertyConfig.m_displayName = "Material Type";
|
||||
propertyConfig.m_groupName = "Details";
|
||||
propertyConfig.m_groupName = "Overview";
|
||||
propertyConfig.m_description = "The material type defines the layout, properties, default values, shader connections, and other "
|
||||
"data needed to create and edit a derived material.";
|
||||
propertyConfig.m_defaultValue = AZStd::any(materialTypeAsset);
|
||||
@@ -834,10 +834,10 @@ namespace MaterialEditor
|
||||
|
||||
propertyConfig = {};
|
||||
propertyConfig.m_dataType = AtomToolsFramework::DynamicPropertyType::Asset;
|
||||
propertyConfig.m_id = "details.parentMaterial";
|
||||
propertyConfig.m_id = "overview.parentMaterial";
|
||||
propertyConfig.m_nameId = "parentMaterial";
|
||||
propertyConfig.m_displayName = "Parent Material";
|
||||
propertyConfig.m_groupName = "Details";
|
||||
propertyConfig.m_groupName = "Overview";
|
||||
propertyConfig.m_description =
|
||||
"The parent material provides an initial configuration whose properties are inherited and overriden by a derived material.";
|
||||
propertyConfig.m_defaultValue = AZStd::any(parentMaterialAsset);
|
||||
@@ -860,7 +860,7 @@ namespace MaterialEditor
|
||||
propertyConfig.m_id = MaterialPropertyId(UvGroupName, shaderInput).GetCStr();
|
||||
propertyConfig.m_nameId = shaderInput;
|
||||
propertyConfig.m_displayName = shaderInput;
|
||||
propertyConfig.m_groupName = "UV Names";
|
||||
propertyConfig.m_groupName = "UV Sets";
|
||||
propertyConfig.m_description = shaderInput;
|
||||
propertyConfig.m_defaultValue = uvName;
|
||||
propertyConfig.m_originalValue = uvName;
|
||||
|
||||
+8
-8
@@ -79,8 +79,8 @@ namespace MaterialEditor
|
||||
|
||||
if (!m_documentId.IsNull() && isOpen)
|
||||
{
|
||||
// Create the top group for displaying details about the material
|
||||
AddDetailsGroup();
|
||||
// Create the top group for displaying overview info about the material
|
||||
AddOverviewGroup();
|
||||
// Create groups for displaying editable UV names
|
||||
AddUvNamesGroup();
|
||||
// Create groups for displaying editable properties
|
||||
@@ -105,25 +105,25 @@ namespace MaterialEditor
|
||||
return property && AtomToolsFramework::ArePropertyValuesEqual(property->GetValue(), property->GetConfig().m_parentValue);
|
||||
}
|
||||
|
||||
void MaterialInspector::AddDetailsGroup()
|
||||
void MaterialInspector::AddOverviewGroup()
|
||||
{
|
||||
const AZ::RPI::MaterialTypeSourceData* materialTypeSourceData = nullptr;
|
||||
MaterialDocumentRequestBus::EventResult(
|
||||
materialTypeSourceData, m_documentId, &MaterialDocumentRequestBus::Events::GetMaterialTypeSourceData);
|
||||
|
||||
const AZStd::string groupNameId = "details";
|
||||
const AZStd::string groupDisplayName = "Details";
|
||||
const AZStd::string groupNameId = "overview";
|
||||
const AZStd::string groupDisplayName = "Overview";
|
||||
const AZStd::string groupDescription = materialTypeSourceData->m_description;
|
||||
auto& group = m_groups[groupNameId];
|
||||
|
||||
AtomToolsFramework::DynamicProperty property;
|
||||
MaterialDocumentRequestBus::EventResult(
|
||||
property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("details.materialType"));
|
||||
property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("overview.materialType"));
|
||||
group.m_properties.push_back(property);
|
||||
|
||||
property = {};
|
||||
MaterialDocumentRequestBus::EventResult(
|
||||
property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("details.parentMaterial"));
|
||||
property, m_documentId, &MaterialDocumentRequestBus::Events::GetProperty, AZ::Name("overview.parentMaterial"));
|
||||
group.m_properties.push_back(property);
|
||||
|
||||
// Passing in same group as main and comparison instance to enable custom value comparison for highlighting modified properties
|
||||
@@ -139,7 +139,7 @@ namespace MaterialEditor
|
||||
MaterialDocumentRequestBus::EventResult(materialAsset, m_documentId, &MaterialDocumentRequestBus::Events::GetAsset);
|
||||
|
||||
const AZStd::string groupNameId = UvGroupName;
|
||||
const AZStd::string groupDisplayName = "UV Names";
|
||||
const AZStd::string groupDisplayName = "UV Sets";
|
||||
const AZStd::string groupDescription = "UV set names in this material, which can be renamed to match those in the model.";
|
||||
auto& group = m_groups[groupNameId];
|
||||
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ namespace MaterialEditor
|
||||
bool CompareInstanceNodeProperties(
|
||||
const AzToolsFramework::InstanceDataNode* source, const AzToolsFramework::InstanceDataNode* target) const;
|
||||
|
||||
void AddDetailsGroup();
|
||||
void AddOverviewGroup();
|
||||
void AddUvNamesGroup();
|
||||
void AddPropertiesGroup();
|
||||
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ namespace AZ
|
||||
void MaterialPropertyInspector::AddUvNamesGroup()
|
||||
{
|
||||
const AZStd::string groupNameId = AZ::RPI::UvGroupName;
|
||||
const AZStd::string groupDisplayName = "UV Names";
|
||||
const AZStd::string groupDisplayName = "UV Sets";
|
||||
const AZStd::string groupDescription = "UV set names in this material, which can be renamed to match those in the model.";
|
||||
auto& group = m_groups[groupNameId];
|
||||
|
||||
|
||||
@@ -383,6 +383,8 @@ namespace {{ Component.attrib['Namespace'] }}
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Authority', 'Client', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Authority', 'Autonomous', false)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Authority', 'Autonomous', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Autonomous', 'Authority', false)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Autonomous', 'Authority', true)|indent(8) -}}
|
||||
{{ DeclareArchetypePropertyGetters(Component)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', false)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', true)|indent(8) -}}
|
||||
@@ -456,7 +458,6 @@ namespace {{ Component.attrib['Namespace'] }}
|
||||
{% endif %}
|
||||
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Server', false)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Autonomous', false)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Client', false)|indent(8) -}}
|
||||
{{ DeclareArchetypePropertyGetters(Component)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', false)|indent(8) -}}
|
||||
@@ -481,8 +482,6 @@ namespace {{ Component.attrib['Namespace'] }}
|
||||
//! @}
|
||||
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Server', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Autonomous', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Autonomous', 'Authority', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Client', true)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', true)|indent(8) -}}
|
||||
{{ AutoComponentMacros.DeclareRpcHandlers(Component, 'Authority', 'Client', false)|indent(8) -}}
|
||||
|
||||
@@ -796,12 +796,27 @@ enum class NetworkProperties
|
||||
AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str())
|
||||
return {{ Property.attrib['Type'] }}();
|
||||
}
|
||||
{% if (ReplicateTo == 'Autonomous') or (ReplicateFrom == 'Autonomous' and ReplicateTo == 'Authority') %}
|
||||
|
||||
// {{ UpperFirst(Property.attrib['Name']) }} is only sent and received between contoller objects (ie Authority, Autonomous); we must go through the controller in order to get this property
|
||||
{{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController());
|
||||
if (!controller)
|
||||
{
|
||||
AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) {{ ClassName }} is missing the network controller. This property is replicated to autonomous network entities, because this entity doesn't have a controller, it must not be automonous. Please check your network context before attempting to get {{ UpperFirst(Property.attrib['Name']) }}.", entity->GetName().c_str(), id.ToString().c_str())
|
||||
return {{ Property.attrib['Type'] }}();
|
||||
}
|
||||
{% if Property.attrib['Container'] == 'Vector' or Property.attrib['Container'] == 'Array' %}
|
||||
return controller->Get{{ UpperFirst(Property.attrib['Name']) }}(index);
|
||||
{% else %}
|
||||
return controller->Get{{ UpperFirst(Property.attrib['Name']) }}();
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if Property.attrib['Container'] == 'Vector' or Property.attrib['Container'] == 'Array' %}
|
||||
return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}(index);
|
||||
{% else %}
|
||||
return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}();
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
})
|
||||
{% if Property.attrib['Container'] == 'Vector' or Property.attrib['Container'] == 'Array' %}
|
||||
->Method("Set{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id, int32_t index, const {{ Property.attrib['Type'] }}& value) -> void
|
||||
@@ -1480,12 +1495,8 @@ namespace {{ Component.attrib['Namespace'] }}
|
||||
}
|
||||
|
||||
{{ DefineNetworkPropertyGets(Component, 'Authority', 'Server', false, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineNetworkPropertyGets(Component, 'Authority', 'Autonomous', false, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineNetworkPropertyGets(Component, 'Autonomous', 'Authority', false, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineNetworkPropertyGets(Component, 'Authority', 'Client', false, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineNetworkPropertyGets(Component, 'Authority', 'Server', true, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineNetworkPropertyGets(Component, 'Authority', 'Autonomous', true, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineNetworkPropertyGets(Component, 'Autonomous', 'Authority', true, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineNetworkPropertyGets(Component, 'Authority', 'Client', true, ComponentBaseName)|indent(4) }}
|
||||
{{ DefineArchetypePropertyGets(Component, ClassType, ComponentBaseName)|indent(4) -}}
|
||||
{{ DefineRpcInvocations(Component, ComponentBaseName, 'Server', 'Authority', false)|indent(4) -}}
|
||||
|
||||
@@ -438,19 +438,16 @@ namespace Multiplayer
|
||||
m_connAcquiredEvent.Signal(datum);
|
||||
}
|
||||
|
||||
// Hosts will spawn a new default player prefab for the user that just connected
|
||||
if (GetAgentType() == MultiplayerAgentType::ClientServer
|
||||
|| GetAgentType() == MultiplayerAgentType::DedicatedServer)
|
||||
{
|
||||
PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast<AZ::CVarFixedString>(sv_defaultPlayerSpawnAsset).c_str()), 1);
|
||||
INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity());
|
||||
|
||||
NetworkEntityHandle controlledEntity;
|
||||
if (entityList.size() > 0)
|
||||
NetworkEntityHandle controlledEntity = SpawnDefaultPlayerPrefab();
|
||||
if (controlledEntity.Exists())
|
||||
{
|
||||
controlledEntity = entityList[0];
|
||||
controlledEntity.GetNetBindComponent()->SetOwningConnectionId(connection->GetConnectionId());
|
||||
}
|
||||
|
||||
|
||||
if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so
|
||||
{
|
||||
connection->SetUserData(new ServerToClientConnectionData(connection, *this, controlledEntity));
|
||||
@@ -522,6 +519,17 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
m_agentType = multiplayerType;
|
||||
|
||||
// Spawn the default player for this host since the host is also a player (not a dedicated server)
|
||||
if (m_agentType == MultiplayerAgentType::ClientServer)
|
||||
{
|
||||
NetworkEntityHandle controlledEntity = SpawnDefaultPlayerPrefab();
|
||||
if (NetBindComponent* controlledEntityNetBindComponent = controlledEntity.GetNetBindComponent())
|
||||
{
|
||||
controlledEntityNetBindComponent->SetAllowAutonomy(true);
|
||||
}
|
||||
}
|
||||
|
||||
AZLOG_INFO("Multiplayer operating in %s mode", GetEnumString(m_agentType));
|
||||
}
|
||||
|
||||
@@ -629,6 +637,19 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
|
||||
NetworkEntityHandle MultiplayerSystemComponent::SpawnDefaultPlayerPrefab()
|
||||
{
|
||||
PrefabEntityId playerPrefabEntityId(AZ::Name(static_cast<AZ::CVarFixedString>(sv_defaultPlayerSpawnAsset).c_str()), 1);
|
||||
INetworkEntityManager::EntityList entityList = m_networkEntityManager.CreateEntitiesImmediate(playerPrefabEntityId, NetEntityRole::Authority, AZ::Transform::CreateIdentity());
|
||||
|
||||
NetworkEntityHandle controlledEntity;
|
||||
if (entityList.size() > 0)
|
||||
{
|
||||
controlledEntity = entityList[0];
|
||||
}
|
||||
return controlledEntity;
|
||||
}
|
||||
|
||||
void host([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
Multiplayer::MultiplayerAgentType serverType = sv_isDedicated ? MultiplayerAgentType::DedicatedServer : MultiplayerAgentType::ClientServer;
|
||||
|
||||
@@ -104,7 +104,8 @@ namespace Multiplayer
|
||||
|
||||
void OnConsoleCommandInvoked(AZStd::string_view command, const AZ::ConsoleCommandContainer& args, AZ::ConsoleFunctorFlags flags, AZ::ConsoleInvokedFrom invokedFrom);
|
||||
void ExecuteConsoleCommandList(AzNetworking::IConnection* connection, const AZStd::fixed_vector<Multiplayer::LongNetworkString, 32>& commands);
|
||||
|
||||
NetworkEntityHandle SpawnDefaultPlayerPrefab();
|
||||
|
||||
AZ_CONSOLEFUNC(MultiplayerSystemComponent, DumpStats, AZ::ConsoleFunctorFlags::Null, "Dumps stats for the current multiplayer session");
|
||||
|
||||
AzNetworking::INetworkInterface* m_networkInterface = nullptr;
|
||||
|
||||
@@ -402,8 +402,12 @@ namespace Multiplayer
|
||||
const AZ::Transform& transform
|
||||
)
|
||||
{
|
||||
INetworkEntityManager::EntityList returnList;
|
||||
|
||||
EntityList returnList;
|
||||
if (!AZ::Data::AssetManager::IsReady())
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
auto spawnableAssetId = m_networkPrefabLibrary.GetAssetIdByName(prefabEntryId.m_prefabName);
|
||||
// Required for sync-instantiation. Todo: keep the reference in NetworkSpawnableLibrary
|
||||
auto netSpawnableAsset = AZ::Data::AssetManager::Instance().GetAsset<AzFramework::Spawnable>(spawnableAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
|
||||
@@ -128,6 +128,9 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AUTOMOC
|
||||
FILES_CMAKE
|
||||
physx_editor_shared_files.cmake
|
||||
COMPILE_DEFINITIONS
|
||||
PUBLIC
|
||||
PHYSX_ENABLE_MULTI_THREADING
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
.
|
||||
|
||||
@@ -13,24 +13,11 @@ if(NOT PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(static_files pythonassetbuilder_common_files.cmake)
|
||||
set(editor_files pythonassetbuilder_editor_files.cmake)
|
||||
set(shared_files pythonassetbuilder_shared_files.cmake)
|
||||
set(static_dependencies
|
||||
3rdParty::Python
|
||||
Gem::EditorPythonBindings.Static
|
||||
AZ::AssetBuilderSDK
|
||||
)
|
||||
set(editor_dependencies
|
||||
Gem::EditorPythonBindings.Static
|
||||
AZ::AssetBuilderSDK
|
||||
)
|
||||
|
||||
ly_add_target(
|
||||
NAME PythonAssetBuilder.Static STATIC
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
${static_files}
|
||||
pythonassetbuilder_common_files.cmake
|
||||
PLATFORM_INCLUDE_FILES
|
||||
Source/Platform/Common/${PAL_TRAIT_COMPILER_ID}/pythonassetbuilder_static_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
@@ -43,7 +30,9 @@ ly_add_target(
|
||||
PRIVATE
|
||||
AZ::AzCore
|
||||
PUBLIC
|
||||
${static_dependencies}
|
||||
3rdParty::Python
|
||||
Gem::EditorPythonBindings.Static
|
||||
AZ::AssetBuilderSDK
|
||||
AZ::AzToolsFramework
|
||||
)
|
||||
|
||||
@@ -52,8 +41,8 @@ ly_add_target(
|
||||
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
${editor_files}
|
||||
${shared_files}
|
||||
pythonassetbuilder_editor_files.cmake
|
||||
pythonassetbuilder_shared_files.cmake
|
||||
PLATFORM_INCLUDE_FILES
|
||||
Source/Platform/Common/${PAL_TRAIT_COMPILER_ID}/pythonassetbuilder_static_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
@@ -64,7 +53,8 @@ ly_add_target(
|
||||
Include
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
${editor_dependencies}
|
||||
Gem::EditorPythonBindings.Static
|
||||
AZ::AssetBuilderSDK
|
||||
RUNTIME_DEPENDENCIES
|
||||
Gem::EditorPythonBindings.Editor
|
||||
)
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace ScriptCanvas::Nodeables::Spawning
|
||||
AZ::Vector3 rotationCopy = rotation;
|
||||
AZ::Quaternion rotationQuat = AZ::Quaternion::CreateFromEulerAnglesDegrees(rotationCopy);
|
||||
|
||||
entityTransform->SetWorldTM(AZ::Transform(translation, rotationQuat, AZ::Vector3(scale, scale, scale)));
|
||||
entityTransform->SetWorldTM(AZ::Transform(translation, rotationQuat, scale));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -118,11 +118,6 @@ If you have the Git credential manager core or other credential helpers installe
|
||||
```
|
||||
python\get_python.bat
|
||||
```
|
||||
|
||||
1. While still within the repo folder, register the engine with this command:
|
||||
```
|
||||
scripts\o3de.bat register --this-engine
|
||||
```
|
||||
|
||||
1. Configure the source into a solution using this command line, replacing <your build path> and <3rdParty cache path> to a path you've created:
|
||||
```
|
||||
@@ -146,7 +141,11 @@ If you have the Git credential manager core or other credential helpers installe
|
||||
|
||||
1. This will compile after some time and binaries will be available in the build path you've specified
|
||||
|
||||
### Setting up new projects
|
||||
### Setting up new projects
|
||||
1. While still within the repo folder, register the engine with this command:
|
||||
```
|
||||
scripts\o3de.bat register --this-engine
|
||||
```
|
||||
1. Setup new projects using the `o3de create-project` command. In the 0.5 branch, the project directory must be a subdirectory in the repo folder.
|
||||
```
|
||||
<Repo path>\scripts\o3de.bat create-project --project-path <your new project path>
|
||||
@@ -160,10 +159,10 @@ If you have the Git credential manager core or other credential helpers installe
|
||||
cmake -B <your project build path> -S <your new project source path> -G "Visual Studio 16" -DLY_3RDPARTY_PATH=<3rdParty cache path>
|
||||
|
||||
// For the 0.5 branch, you must build a new Editor for each project:
|
||||
cmake --build <your project build path> --target <New Project Name> Editor --config profile -- /m
|
||||
cmake --build <your project build path> --target <New Project Name>.GameLauncher Editor --config profile -- /m
|
||||
|
||||
// For all other branches, just build the project:
|
||||
cmake --build <your project build path> --target <New Project Name> --config profile -- /m
|
||||
cmake --build <your project build path> --target <New Project Name>.GameLauncher --config profile -- /m
|
||||
```
|
||||
|
||||
For a tutorial on project configuration, see [Creating Projects Using the Command Line](https://docs.o3de.org/docs/welcome-guide/get-started/project-config/creating-projects-using-cli) in the documentation.
|
||||
|
||||
@@ -105,7 +105,7 @@ function(ly_get_runtime_dependencies ly_RUNTIME_DEPENDENCIES ly_TARGET)
|
||||
set(skip_imported TRUE)
|
||||
endif()
|
||||
endif()
|
||||
if(target_type MATCHES "(INTERFACE_LIBRARY|STATIC_LIBRARY)")
|
||||
if(target_type MATCHES "(STATIC_LIBRARY)")
|
||||
# No need to copy these dependencies since the outputs are not used at runtime
|
||||
set(skip_imported TRUE)
|
||||
endif()
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#
|
||||
|
||||
import imghdr
|
||||
import configparser
|
||||
import datetime
|
||||
import fnmatch
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
@@ -33,6 +35,13 @@ if ROOT_DEV_PATH not in sys.path:
|
||||
from cmake.Tools import common
|
||||
|
||||
|
||||
ANDROID_GRADLE_PLUGIN_COMPATIBILITY_MAP = {
|
||||
'4.2.0': {'min_gradle_version': '6.7.1',
|
||||
'sdk_build': '30.0.2',
|
||||
'default_ndk': '21.4.7075529',
|
||||
'min_cmake_version': '3.20'}
|
||||
}
|
||||
|
||||
APP_NAME = 'app'
|
||||
ANDROID_MANIFEST_FILE = 'AndroidManifest.xml'
|
||||
ANDROID_LIBRARIES_JSON_FILE = 'android_libraries.json'
|
||||
@@ -86,83 +95,93 @@ PYTHON_SCRIPT = 'python.cmd' if platform.system() == 'Windows' else 'python.sh'
|
||||
|
||||
ANDROID_LAUNCHER_NAME_PATTERN = "{project_name}.GameLauncher"
|
||||
|
||||
|
||||
class AndroidProjectManifestEnvironment(object):
|
||||
"""
|
||||
This class manages the environment for the AndroidManifiest.xml template file, based on project settings and environments
|
||||
This class manages the environment for the AndroidManifest.xml template file, based on project settings and environments
|
||||
that were passed in or calculated from the command line arguments.
|
||||
"""
|
||||
|
||||
def __init__(self, engine_root, project_path, android_sdk_version_number, android_ndk_platform_number, is_test:bool):
|
||||
def __init__(self, engine_root, project_path, android_sdk_version_number, is_test:bool):
|
||||
"""
|
||||
Initialize the object with the project specific parameters and values for the game project
|
||||
|
||||
:param engine_root: The path where the engine is located
|
||||
:param project_path: The path were the project is located
|
||||
:param android_sdk_version_number: The android SDK platform version
|
||||
:param android_ndk_platform_number: The android NDK platform version
|
||||
:param is_test: Indicates if theAzTestRunner application should be run
|
||||
"""
|
||||
|
||||
if is_test:
|
||||
# The AzTestRunner project.json is located under {engine_root}/Code/Tools/AzTestRunner/Platform/Android/android_project.json
|
||||
project_properties_path = engine_root / 'Code' / 'Tools' / 'AzTestRunner' / 'Platform' / 'Android' / 'android_project.json'
|
||||
else:
|
||||
# The project.json file is located under the game name folder
|
||||
project_properties_path = project_path / 'project.json'
|
||||
# Read and parse the project.json file into a dictionary to process the specific attributes needed for the manifest template
|
||||
project_properties_content = project_properties_path.resolve(strict=True)\
|
||||
.read_text(encoding=common.DEFAULT_TEXT_READ_ENCODING,
|
||||
errors=common.ENCODING_ERROR_HANDLINGS)
|
||||
self.project_path = project_path
|
||||
try:
|
||||
if is_test:
|
||||
# The AzTestRunner project.json is located under {engine_root}/Code/Tools/AzTestRunner/Platform/Android/android_project.json
|
||||
project_properties_path = engine_root / 'Code' / 'Tools' / 'AzTestRunner' / 'Platform' / 'Android' / 'android_project.json'
|
||||
assert project_properties_path.is_file(), f'Missing required android settings file {project_properties_path.resolve()}'
|
||||
project_properties_content = project_properties_path.read_text(encoding=common.DEFAULT_TEXT_READ_ENCODING,
|
||||
errors=common.ENCODING_ERROR_HANDLINGS)
|
||||
project_json = json.loads(project_properties_content)
|
||||
|
||||
# Extract the key attributes we need to process and build up our environment table
|
||||
project_json = json.loads(project_properties_content)
|
||||
android_settings = project_json['android_settings']
|
||||
|
||||
project_name = project_json.get('project_name')
|
||||
if not project_name:
|
||||
raise common.LmbrCmdError(f"Missing required 'project_name' from project.json for project at '{str(project_path)}'")
|
||||
product_name = project_json.get('product_name', project_name)
|
||||
else:
|
||||
# O3DE projects have both a project.json and an android_project.json files (unless its internal)
|
||||
project_properties_path = project_path / 'project.json'
|
||||
assert project_properties_path.is_file(), f'Missing required project settings file {project_properties_path.resolve()}'
|
||||
project_properties_content = project_properties_path.read_text(encoding=common.DEFAULT_TEXT_READ_ENCODING,
|
||||
errors=common.ENCODING_ERROR_HANDLINGS)
|
||||
project_json = json.loads(project_properties_content)
|
||||
|
||||
game_project_android_settings = project_json['android_settings']
|
||||
android_project_properties_path = project_path / 'Platform' / 'Android' / 'android_project.json'
|
||||
if android_project_properties_path.is_file():
|
||||
android_project_properties_content = android_project_properties_path.read_text(encoding=common.DEFAULT_TEXT_READ_ENCODING,
|
||||
errors=common.ENCODING_ERROR_HANDLINGS)
|
||||
android_project_json = json.loads(android_project_properties_content)
|
||||
android_settings = android_project_json['android_settings']
|
||||
else:
|
||||
android_settings = project_json['android_settings']
|
||||
|
||||
package_name = game_project_android_settings["package_name"]
|
||||
self.project_path = project_path
|
||||
|
||||
package_path = package_name.replace('.', '/')
|
||||
project_name = project_json['project_name']
|
||||
product_name = project_json.get('product_name', project_name)
|
||||
package_name = android_settings["package_name"]
|
||||
package_path = package_name.replace('.', '/')
|
||||
|
||||
project_activity = f'{TEST_RUNNER_PROJECT}Activity' if is_test else f'{project_name}Activity'
|
||||
project_activity = f'{TEST_RUNNER_PROJECT}Activity' if is_test else f'{project_name}Activity'
|
||||
|
||||
# Multiview options require special processing
|
||||
multi_window_options = AndroidProjectManifestEnvironment.process_android_multi_window_options(game_project_android_settings)
|
||||
# Multiview options require special processing
|
||||
multi_window_options = AndroidProjectManifestEnvironment.process_android_multi_window_options(android_settings)
|
||||
|
||||
self.internal_dict = {
|
||||
'ANDROID_PACKAGE': package_name,
|
||||
'ANDROID_PACKAGE_PATH': package_path,
|
||||
'ANDROID_VERSION_NUMBER': game_project_android_settings["version_number"],
|
||||
"ANDROID_VERSION_NAME": game_project_android_settings["version_name"],
|
||||
"ANDROID_SCREEN_ORIENTATION": game_project_android_settings["orientation"],
|
||||
'ANDROID_APP_NAME': TEST_RUNNER_PROJECT if is_test else product_name, # external facing name
|
||||
'ANDROID_PROJECT_NAME': TEST_RUNNER_PROJECT if is_test else project_name, # internal facing name
|
||||
'ANDROID_PROJECT_ACTIVITY': project_activity,
|
||||
'ANDROID_LAUNCHER_NAME': TEST_RUNNER_PROJECT if is_test else ANDROID_LAUNCHER_NAME_PATTERN.format(project_name=project_name),
|
||||
'ANDROID_CONFIG_CHANGES': multi_window_options['ANDROID_CONFIG_CHANGES'],
|
||||
'ANDROID_APP_PUBLIC_KEY': game_project_android_settings.get('app_public_key', 'NoKey'),
|
||||
'ANDROID_APP_OBFUSCATOR_SALT': game_project_android_settings.get('app_obfuscator_salt', ''),
|
||||
'ANDROID_USE_MAIN_OBB': game_project_android_settings.get('use_main_obb', 'false'),
|
||||
'ANDROID_USE_PATCH_OBB': game_project_android_settings.get('use_patch_obb', 'false'),
|
||||
'ANDROID_ENABLE_KEEP_SCREEN_ON': game_project_android_settings.get('enable_keep_screen_on', 'false'),
|
||||
'ANDROID_DISABLE_IMMERSIVE_MODE': game_project_android_settings.get('disable_immersive_mode', 'false'),
|
||||
'ANDROID_MIN_SDK_VERSION': android_ndk_platform_number,
|
||||
'ANDROID_TARGET_SDK_VERSION': android_sdk_version_number,
|
||||
'ICONS': game_project_android_settings.get('icons', None),
|
||||
'SPLASH_SCREEN': game_project_android_settings.get('splash_screen', None),
|
||||
self.internal_dict = {
|
||||
'ANDROID_PACKAGE': package_name,
|
||||
'ANDROID_PACKAGE_PATH': package_path,
|
||||
'ANDROID_VERSION_NUMBER': android_settings["version_number"],
|
||||
"ANDROID_VERSION_NAME": android_settings["version_name"],
|
||||
"ANDROID_SCREEN_ORIENTATION": android_settings["orientation"],
|
||||
'ANDROID_APP_NAME': TEST_RUNNER_PROJECT if is_test else product_name, # external facing name
|
||||
'ANDROID_PROJECT_NAME': TEST_RUNNER_PROJECT if is_test else project_name, # internal facing name
|
||||
'ANDROID_PROJECT_ACTIVITY': project_activity,
|
||||
'ANDROID_LAUNCHER_NAME': TEST_RUNNER_PROJECT if is_test else ANDROID_LAUNCHER_NAME_PATTERN.format(project_name=project_name),
|
||||
'ANDROID_CONFIG_CHANGES': multi_window_options['ANDROID_CONFIG_CHANGES'],
|
||||
'ANDROID_APP_PUBLIC_KEY': android_settings.get('app_public_key', 'NoKey'),
|
||||
'ANDROID_APP_OBFUSCATOR_SALT': android_settings.get('app_obfuscator_salt', ''),
|
||||
'ANDROID_USE_MAIN_OBB': android_settings.get('use_main_obb', 'false'),
|
||||
'ANDROID_USE_PATCH_OBB': android_settings.get('use_patch_obb', 'false'),
|
||||
'ANDROID_ENABLE_KEEP_SCREEN_ON': android_settings.get('enable_keep_screen_on', 'false'),
|
||||
'ANDROID_DISABLE_IMMERSIVE_MODE': android_settings.get('disable_immersive_mode', 'false'),
|
||||
'ANDROID_TARGET_SDK_VERSION': android_sdk_version_number,
|
||||
'ICONS': android_settings.get('icons', None),
|
||||
'SPLASH_SCREEN': android_settings.get('splash_screen', None),
|
||||
|
||||
'ANDROID_MULTI_WINDOW': multi_window_options['ANDROID_MULTI_WINDOW'],
|
||||
'ANDROID_MULTI_WINDOW_PROPERTIES': multi_window_options['ANDROID_MULTI_WINDOW_PROPERTIES'],
|
||||
'ANDROID_MULTI_WINDOW': multi_window_options['ANDROID_MULTI_WINDOW'],
|
||||
'ANDROID_MULTI_WINDOW_PROPERTIES': multi_window_options['ANDROID_MULTI_WINDOW_PROPERTIES'],
|
||||
|
||||
'SAMSUNG_DEX_KEEP_ALIVE': multi_window_options['SAMSUNG_DEX_KEEP_ALIVE'],
|
||||
'SAMSUNG_DEX_LAUNCH_WIDTH': multi_window_options['SAMSUNG_DEX_LAUNCH_WIDTH'],
|
||||
'SAMSUNG_DEX_LAUNCH_HEIGHT': multi_window_options['SAMSUNG_DEX_LAUNCH_HEIGHT']
|
||||
}
|
||||
'SAMSUNG_DEX_KEEP_ALIVE': multi_window_options['SAMSUNG_DEX_KEEP_ALIVE'],
|
||||
'SAMSUNG_DEX_LAUNCH_WIDTH': multi_window_options['SAMSUNG_DEX_LAUNCH_WIDTH'],
|
||||
'SAMSUNG_DEX_LAUNCH_HEIGHT': multi_window_options['SAMSUNG_DEX_LAUNCH_HEIGHT']
|
||||
}
|
||||
except KeyError as e:
|
||||
raise common.LmbrCmdError(f"Missing key from android project settings for project at {project_path}:'{e}' ")
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.internal_dict.get(item)
|
||||
@@ -306,6 +325,7 @@ asset_deploy_type={asset_type}
|
||||
android_sdk_path={android_sdk_path}
|
||||
embed_assets_in_apk={embed_assets_in_apk}
|
||||
is_unit_test={is_unit_test}
|
||||
android_gradle_plugin={android_gradle_plugin_version}
|
||||
"""
|
||||
|
||||
NATIVE_CMAKE_SECTION_ANDROID_FORMAT = """
|
||||
@@ -425,26 +445,28 @@ class AndroidProjectGenerator(object):
|
||||
Class the manages the process to generate an android project folder in order to build with gradle/android studio
|
||||
"""
|
||||
|
||||
def __init__(self, engine_root, build_dir, android_ndk_path, android_sdk_path, android_sdk_version, android_ndk_platform,
|
||||
project_path, third_party_path, cmake_version, override_cmake_path, override_gradle_path, override_ninja_path,
|
||||
android_sdk_build_tool_version, include_assets_in_apk, asset_mode, asset_type, signing_config, is_test_project=False,
|
||||
def __init__(self, engine_root, build_dir, android_sdk_path, build_tool, android_sdk_platform, android_native_api_level, android_ndk,
|
||||
project_path, third_party_path, cmake_version, override_cmake_path, override_gradle_path, gradle_version, gradle_plugin_version,
|
||||
override_ninja_path, include_assets_in_apk, asset_mode, asset_type, signing_config, is_test_project=False,
|
||||
overwrite_existing=True):
|
||||
"""
|
||||
Initialize the object with all the required parameters needed to create an Android Project. The parameters should be verified before initializing this object
|
||||
|
||||
|
||||
:param engine_root: The engine root that contains the engine
|
||||
:param build_dir: The target folder under the where the android project folder will be created
|
||||
:param android_ndk_path: The path to the ANDROID_NDK used for building the native android code
|
||||
:param android_sdk_path: The path to the ANDROID_SDK used for building the android java code
|
||||
:param android_sdk_version: The android platform version number to use for the Android SDK related builds
|
||||
:param android_ndk_platform: The android platform version number to use for the Android NDK related builds
|
||||
:param build_tool: The android SDK build-tool version.
|
||||
:param android_sdk_platform: The android sdk platform version number to use for the Android SDK related builds
|
||||
:param android_native_api_level:The android native API level (ANDROID_NATIVE_API_LEVEL) to set
|
||||
:param android_ndk: The android ndk version number to use for the native builds
|
||||
:param project_path: The path to the project
|
||||
:param third_party_path: The required path to the lumberyard 3rd party path
|
||||
:param cmake_version: The version number of cmake that will be used by gradle
|
||||
:param override_cmake_path: The override path to cmake if it does not exists in the system path
|
||||
:param override_gradle_path: The override path to gradle if it does not exists in the system path
|
||||
:param gradle_version: The detected version of gradle being used
|
||||
:param gradle_plugin_version: The android gradle plugin version
|
||||
:param override_ninja_path: The override path to ninja if it does not exists in the system path
|
||||
:param android_sdk_build_tool_version: The preferred android SDK build-tool version. Will default to the first one detected in the android sdk path
|
||||
:param include_assets_in_apk:
|
||||
:param asset_mode:
|
||||
:param asset_type:
|
||||
@@ -458,17 +480,16 @@ class AndroidProjectGenerator(object):
|
||||
|
||||
self.build_dir = build_dir
|
||||
|
||||
self.android_ndk_path = android_ndk_path
|
||||
|
||||
self.android_sdk_path = android_sdk_path
|
||||
|
||||
self.android_project_builder_path = self.engine_root / 'Code/Tools/Android/ProjectBuilder'
|
||||
|
||||
self.android_sdk_version = android_sdk_version
|
||||
self.android_sdk_platform = android_sdk_platform
|
||||
self.android_sdk_build_tool_version = build_tool.version
|
||||
|
||||
self.android_sdk_build_tool_version = android_sdk_build_tool_version
|
||||
|
||||
self.android_ndk_platform = android_ndk_platform
|
||||
self.android_ndk = android_ndk
|
||||
self.android_ndk_version = android_ndk.version
|
||||
self.android_native_api_level = android_native_api_level
|
||||
|
||||
self.project_path = project_path
|
||||
|
||||
@@ -480,6 +501,10 @@ class AndroidProjectGenerator(object):
|
||||
|
||||
self.override_gradle_path = override_gradle_path
|
||||
|
||||
self.gradle_version = gradle_version
|
||||
|
||||
self.gradle_plugin_version = gradle_plugin_version
|
||||
|
||||
self.override_ninja_path = override_ninja_path
|
||||
|
||||
self.include_assets_in_apk = include_assets_in_apk
|
||||
@@ -511,8 +536,10 @@ class AndroidProjectGenerator(object):
|
||||
project_names.extend(self.create_lumberyard_app(project_names))
|
||||
|
||||
root_gradle_env = {
|
||||
'SDK_VER': self.android_sdk_version,
|
||||
'NDK_PLATFORM_VER': self.android_ndk_platform,
|
||||
'ANDROID_GRADLE_PLUGIN_VERSION': str(self.gradle_plugin_version),
|
||||
'SDK_VER': self.android_sdk_platform,
|
||||
'MIN_SDK_VER': self.android_sdk_platform,
|
||||
'NDK_VERSION': self.android_ndk_version,
|
||||
'SDK_BUILD_TOOL_VER': self.android_sdk_build_tool_version,
|
||||
'LY_ENGINE_ROOT': common.normalize_path_for_settings(self.engine_root)
|
||||
}
|
||||
@@ -557,7 +584,7 @@ class AndroidProjectGenerator(object):
|
||||
if self.override_gradle_path:
|
||||
gradle_wrapper_cmd = [self.override_gradle_path]
|
||||
else:
|
||||
gradle_wrapper_cmd = ['gradle.bat' if platform.system() == 'Windows' else 'gradle']
|
||||
gradle_wrapper_cmd = ['gradle']
|
||||
|
||||
gradle_wrapper_cmd.extend(['wrapper', '-p', str(self.build_dir.resolve())])
|
||||
|
||||
@@ -580,7 +607,8 @@ class AndroidProjectGenerator(object):
|
||||
asset_type='',
|
||||
android_sdk_path=str(self.android_sdk_path),
|
||||
embed_assets_in_apk=True,
|
||||
is_unit_test=True)
|
||||
is_unit_test=True,
|
||||
android_gradle_plugin_version=self.gradle_plugin_version)
|
||||
else:
|
||||
platform_settings_content = PLATFORM_SETTINGS_FORMAT.format(generation_timestamp=str(datetime.datetime.now().strftime("%c")),
|
||||
platform='android',
|
||||
@@ -589,16 +617,28 @@ class AndroidProjectGenerator(object):
|
||||
asset_type=self.asset_type,
|
||||
android_sdk_path=str(self.android_sdk_path),
|
||||
embed_assets_in_apk=str(self.include_assets_in_apk),
|
||||
is_unit_test=False)
|
||||
is_unit_test=False,
|
||||
android_gradle_plugin_version=self.gradle_plugin_version)
|
||||
|
||||
platform_settings_file = self.build_dir / 'platform.settings'
|
||||
|
||||
# Check if there already exists the build folder and a 'platform.settings' file. If there is an android gradle
|
||||
# plugin version set and it is different than the one configured here, we will always overwrite it since
|
||||
# there could be significant differences from one plug-in to the next
|
||||
if platform_settings_file.is_file():
|
||||
config = configparser.ConfigParser()
|
||||
config.read([str(platform_settings_file.resolve(strict=True))])
|
||||
if config.has_option('android', 'android_gradle_plugin'):
|
||||
exist_agp_version = config.get('android', 'android_gradle_plugin')
|
||||
if exist_agp_version != self.gradle_plugin_version:
|
||||
self.overwrite_existing = True
|
||||
|
||||
platform_settings_file.open('w').write(platform_settings_content)
|
||||
|
||||
def create_default_local_properties(self):
|
||||
"""
|
||||
Create the default 'local.properties' file in the build folder
|
||||
"""
|
||||
template_android_ndk_path = common.normalize_path_for_settings(self.android_ndk_path, True)
|
||||
template_android_sdk_path = common.normalize_path_for_settings(self.android_sdk_path, True)
|
||||
if self.override_cmake_path:
|
||||
# The cmake dir references the base cmake folder, not the executable path itself, so resolve to the base folder
|
||||
@@ -608,7 +648,6 @@ class AndroidProjectGenerator(object):
|
||||
|
||||
local_properties_env = {
|
||||
"GENERATION_TIMESTAMP": str(datetime.datetime.now().strftime("%c")),
|
||||
"ANDROID_NDK_PATH": template_android_ndk_path,
|
||||
"ANDROID_SDK_PATH": template_android_sdk_path,
|
||||
"CMAKE_DIR_LINE": f'cmake.dir={template_cmake_path}' if template_cmake_path else ''
|
||||
}
|
||||
@@ -626,8 +665,7 @@ class AndroidProjectGenerator(object):
|
||||
# before we can process it.
|
||||
android_libraries_substitution_table = {
|
||||
"ANDROID_SDK_HOME": common.normalize_path_for_settings(self.android_sdk_path, False),
|
||||
"ANDROID_NDK_HOME": common.normalize_path_for_settings(self.android_ndk_path, False),
|
||||
"ANDROID_SDK_VERSION": "android-".format(self.android_sdk_version)
|
||||
"ANDROID_SDK_VERSION": f"android-{self.android_sdk_platform}"
|
||||
}
|
||||
android_libraries_template_json_path = self.android_project_builder_path / ANDROID_LIBRARIES_JSON_FILE
|
||||
|
||||
@@ -717,7 +755,7 @@ class AndroidProjectGenerator(object):
|
||||
|
||||
template_engine_root = common.normalize_path_for_settings(self.engine_root)
|
||||
template_third_party_path = common.normalize_path_for_settings(self.third_party_path)
|
||||
template_ndk_path = common.normalize_path_for_settings(self.android_ndk_path)
|
||||
template_ndk_path = common.normalize_path_for_settings(os.path.join(self.android_sdk_path, self.android_ndk.location))
|
||||
|
||||
gradle_build_env = dict()
|
||||
|
||||
@@ -733,7 +771,6 @@ class AndroidProjectGenerator(object):
|
||||
|
||||
gradle_build_env['OVERRIDE_JAVA_SOURCESET'] = OVERRIDE_JAVA_SOURCESET_STR.format(absolute_azandroid_path=absolute_azandroid_path)
|
||||
|
||||
|
||||
gradle_build_env['OPTIONAL_JNI_SRC_LIB_SET'] = ', "outputs/native-lib"'
|
||||
|
||||
for native_config in BUILD_CONFIGURATIONS:
|
||||
@@ -755,7 +792,7 @@ class AndroidProjectGenerator(object):
|
||||
cmake_argument_list.append('"-DLY_TEST_PROJECT=1"')
|
||||
|
||||
cmake_argument_list.extend([
|
||||
f'"-DANDROID_NATIVE_API_LEVEL={self.android_ndk_platform}"',
|
||||
f'"-DANDROID_NATIVE_API_LEVEL={self.android_native_api_level}"',
|
||||
f'"-DLY_NDK_DIR={template_ndk_path}"',
|
||||
'"-DANDROID_STL=c++_shared"',
|
||||
'"-Wno-deprecated"',
|
||||
@@ -835,8 +872,7 @@ class AndroidProjectGenerator(object):
|
||||
dest_src_main_path.mkdir(parents=True)
|
||||
az_android_package_env = AndroidProjectManifestEnvironment(engine_root=self.engine_root,
|
||||
project_path=self.project_path,
|
||||
android_sdk_version_number=self.android_sdk_version,
|
||||
android_ndk_platform_number=self.android_ndk_platform,
|
||||
android_sdk_version_number=self.android_sdk_platform,
|
||||
is_test=self.is_test_project)
|
||||
self.create_file_from_project_template(src_template_file=ANDROID_MANIFEST_FILE,
|
||||
template_env=az_android_package_env,
|
||||
@@ -1304,218 +1340,7 @@ class AndroidProjectGenerator(object):
|
||||
self.new = new
|
||||
|
||||
|
||||
ANDROID_PLATFORM_PATTERN = re.compile(r'([\w\d]*-)?(\d+\d*)') # Regex to handle android platform naming for both SDKs and NDKs
|
||||
|
||||
|
||||
def validate_android_platform_input(input_android_platform, platform_variable_type, min_version, max_version):
|
||||
"""
|
||||
Helper tool to support android platform number inputs and perform min/max version validation
|
||||
|
||||
:param input_android_platform: The inpuit argument to evaluate
|
||||
:param platform_variable_type: The type of platform version to validate (android sdk / android ndk)
|
||||
:param min_version: The minimum version to validate against
|
||||
:param max_version: The maximum version to validate against
|
||||
:return: The int version of the extracted platform number from the input
|
||||
"""
|
||||
# Validate the platform number's format and against the supported versions
|
||||
platform_number_match = ANDROID_PLATFORM_PATTERN.search(input_android_platform)
|
||||
if not platform_number_match or not platform_number_match.group(2) or (platform_number_match.group(1) and platform_number_match.group(1) != 'android-'):
|
||||
raise common.LmbrCmdError(f"Invalid {platform_variable_type} version value ({input_android_platform}). It must be "
|
||||
f"either 'XX' or android-'XX' where 'XX' is a platform number.",
|
||||
common.ERROR_CODE_INVALID_PARAMETER)
|
||||
|
||||
android_platform_number = int(platform_number_match.group(2))
|
||||
if android_platform_number < min_version:
|
||||
raise common.LmbrCmdError(f"Invalid {platform_variable_type} version value ({input_android_platform}) is less than the minimum "
|
||||
f"supported version ({min_version}).",
|
||||
common.ERROR_CODE_INVALID_PARAMETER)
|
||||
if android_platform_number > max_version:
|
||||
raise common.LmbrCmdError(f"Invalid {platform_variable_type} version value ({input_android_platform}) is greater than the maximum "
|
||||
f"supported version ({max_version}).",
|
||||
common.ERROR_CODE_INVALID_PARAMETER)
|
||||
return android_platform_number
|
||||
|
||||
|
||||
ANDROID_SDK_ENV_NAME = 'ANDROID_SDK'
|
||||
ANDROID_SDK_MIN_PLATFORM = 28
|
||||
ANDROID_SDK_MAX_PLATFORM = 29
|
||||
|
||||
|
||||
def verify_android_sdk(android_sdk_platform, argument_name, override_android_sdk_path=None, preferred_sdk_build_tools_ver=None):
|
||||
"""
|
||||
Verify the android sdk and the requested platform platform against the android sdk path
|
||||
|
||||
:param android_sdk_platform: The android sdk platform to use (e.g. '28' or 'android-28')
|
||||
:param argument_name: The name of the argument for descriptive errors to present
|
||||
:param override_android_sdk_path: The location of the android SDK path if not set through the environment variable
|
||||
:param preferred_sdk_build_tools_ver: Option prefered built tool version under the android SDK if available. Will fallback to the first one discovered
|
||||
:returns tuple of the verified android sdk platform number, path to the Android SDK path and the build tool version
|
||||
"""
|
||||
android_sdk_platform_number = validate_android_platform_input(input_android_platform=android_sdk_platform,
|
||||
platform_variable_type='android sdk',
|
||||
min_version=ANDROID_SDK_MIN_PLATFORM,
|
||||
max_version=ANDROID_SDK_MAX_PLATFORM)
|
||||
|
||||
# Get the candidate android sdk path from either the override argument or the system environment variable
|
||||
if override_android_sdk_path:
|
||||
check_android_sdk_path = override_android_sdk_path
|
||||
else:
|
||||
check_android_sdk_path = os.environ.get(ANDROID_SDK_ENV_NAME)
|
||||
if not check_android_sdk_path:
|
||||
raise common.LmbrCmdError(f"Android SDK path not set. Make sure that either the '{ANDROID_SDK_ENV_NAME}' environment is "
|
||||
f"set or it is passed in through the {argument_name} argument")
|
||||
|
||||
# The android sdk folder structure is expected to have a 'platforms' sub folder based on the android sdk-platform number
|
||||
check_android_sdk_path = pathlib.Path(check_android_sdk_path)
|
||||
android_sdk_platforms_path = check_android_sdk_path / 'platforms'
|
||||
if not android_sdk_platforms_path.is_dir():
|
||||
raise common.LmbrCmdError(f"Invalid Android SDK path '{str(check_android_sdk_path)}': Missing 'platforms' directory.")
|
||||
|
||||
# Collect the available platform numbers from the platforms subdirectory
|
||||
validated_android_platforms = []
|
||||
for dir_item in android_sdk_platforms_path.iterdir():
|
||||
if not dir_item.is_dir():
|
||||
continue
|
||||
check_file = dir_item / 'package.xml'
|
||||
if check_file.is_file():
|
||||
validated_android_platforms.append(dir_item.name)
|
||||
|
||||
if not validated_android_platforms:
|
||||
raise common.LmbrCmdError(f"Invalid Android SDK path '{str(check_android_sdk_path)}': Unable to find any android platforms.")
|
||||
|
||||
# Normalize the android_sdk argument to fit the same folder name pattern
|
||||
android_sdk_platform_name = f'android-{android_sdk_platform_number}'
|
||||
if android_sdk_platform_name not in validated_android_platforms:
|
||||
raise common.LmbrCmdError(f"Android SDK platform {android_sdk_platform_name} is not a valid for the android SDK located under '{str(check_android_sdk_path)}'")
|
||||
|
||||
# Enumerate through the build tools under android sdk
|
||||
android_sdk_build_tools_dir = check_android_sdk_path / 'build-tools'
|
||||
if not android_sdk_build_tools_dir.is_dir():
|
||||
raise common.LmbrCmdError(f"Invalid Android SDK path '{str(check_android_sdk_path)}': Unable to find any built-tools folder.")
|
||||
supported_build_tools = [str(build_tool.name) for build_tool in android_sdk_build_tools_dir.iterdir() if build_tool.is_dir()]
|
||||
if not supported_build_tools:
|
||||
raise common.LmbrCmdError(f"Invalid Android SDK path '{str(check_android_sdk_path)}': Unable to find any built-tools.")
|
||||
if preferred_sdk_build_tools_ver:
|
||||
if preferred_sdk_build_tools_ver in supported_build_tools:
|
||||
validated_build_tool = preferred_sdk_build_tools_ver
|
||||
else:
|
||||
validated_build_tool = supported_build_tools[0]
|
||||
logging.warning("Unable to locate android sdk build tool version {preferred_sdk_build_tools_ver}. Defaulting to version {validated_build_tool}")
|
||||
|
||||
else:
|
||||
validated_build_tool = supported_build_tools[0]
|
||||
|
||||
return android_sdk_platform_number, check_android_sdk_path, validated_build_tool
|
||||
|
||||
|
||||
ANDROID_NDK_ENV_NAME = 'ANDROID_NDK'
|
||||
ANDROID_NDK_MIN_PLATFORM = 21
|
||||
ANDROID_NDK_MAX_PLATFORM = 29
|
||||
ANDROID_NDK_SOURCE_PROPERTIES_REVISION_PATTERN = re.compile(r'Pkg.Revision\s*=\s*(\d+.\d+.\d+)')
|
||||
|
||||
|
||||
def verify_android_ndk(android_ndk_platform, argument_name, override_android_ndk_path=None):
|
||||
"""
|
||||
Verify the android ndk and requested platform against the android ndk path
|
||||
|
||||
:param android_ndk_platform: The android ndk platform to use (e.g. '21' or 'android-21')
|
||||
:param argument_name: The name of the argument for descriptive errors to present
|
||||
:param override_android_ndk_path: The location of the android NDK path if not set through the environment variable
|
||||
:returns tuple of the verified android ndk platform number and the Path to the Android SDK path and the
|
||||
"""
|
||||
|
||||
android_ndk_platform_number = validate_android_platform_input(input_android_platform=android_ndk_platform,
|
||||
platform_variable_type='android ndk',
|
||||
min_version=ANDROID_NDK_MIN_PLATFORM,
|
||||
max_version=ANDROID_NDK_MAX_PLATFORM)
|
||||
|
||||
# Get the candidate android ndk path from either the override argument or the system environment variable
|
||||
if override_android_ndk_path:
|
||||
check_android_ndk_path = str(override_android_ndk_path)
|
||||
else:
|
||||
check_android_ndk_path = os.environ.get(ANDROID_NDK_ENV_NAME)
|
||||
if not check_android_ndk_path:
|
||||
raise common.LmbrCmdError(f"Android NDK path not set. Make sure that either the {ANDROID_NDK_ENV_NAME} environment "
|
||||
f"is set or it is passed in through the {argument_name} argument")
|
||||
check_android_ndk_path = pathlib.Path(check_android_ndk_path)
|
||||
|
||||
# Validate the android ndk path
|
||||
|
||||
# Determine the NDK revision by reading the source.properties file
|
||||
ndk_source_properties_file = check_android_ndk_path / 'source.properties'
|
||||
if not ndk_source_properties_file.is_file():
|
||||
raise common.LmbrCmdError(f"Invalid Android NDK path '{str(check_android_ndk_path)}'. Missing 'source.properties' file.",
|
||||
common.ERROR_CODE_INVALID_PARAMETER)
|
||||
ndk_source_properties_file_content = ndk_source_properties_file.read_text(encoding=common.DEFAULT_TEXT_READ_ENCODING,
|
||||
errors=common.ENCODING_ERROR_HANDLINGS)
|
||||
|
||||
ndk_revision_match = ANDROID_NDK_SOURCE_PROPERTIES_REVISION_PATTERN.search(ndk_source_properties_file_content)
|
||||
if not ndk_revision_match:
|
||||
raise common.LmbrCmdError(f"Invalid Android NDK path '{str(check_android_ndk_path)}'. Unable to extract version from 'source.properties' file.",
|
||||
common.ERROR_CODE_INVALID_PARAMETER)
|
||||
ndk_revision_number = LooseVersion(ndk_revision_match.group(1))
|
||||
logging.info(f"Detected Android NDK Revision {str(ndk_revision_number)}")
|
||||
|
||||
# Collect the supported android platforms from the required 'platforms' folder under the ndk path
|
||||
android_ndk_platforms_path = check_android_ndk_path / 'platforms'
|
||||
if not android_ndk_platforms_path.is_dir():
|
||||
raise common.LmbrCmdError(f"Invalid Android NDK path '{str(check_android_ndk_path)}'. Missing 'platforms' folder.",
|
||||
common.ERROR_CODE_INVALID_PARAMETER)
|
||||
|
||||
validated_android_platforms = []
|
||||
for dir_item in android_ndk_platforms_path.iterdir():
|
||||
if not dir_item.is_dir():
|
||||
continue
|
||||
api_version_match = ANDROID_PLATFORM_PATTERN.search(dir_item.name)
|
||||
if not api_version_match or api_version_match.group(1) != 'android-':
|
||||
continue
|
||||
|
||||
check_lib_path = dir_item / 'arch-arm64/usr/lib'
|
||||
if check_lib_path.is_dir():
|
||||
validated_android_platforms.append(dir_item.name)
|
||||
|
||||
# For NDK revisions 19 and up, there is a mapping file for version numbers that map to other version.
|
||||
platforms_map_aliases = {}
|
||||
if ndk_revision_number >= LooseVersion('19.0.0'):
|
||||
platforms_map_file = check_android_ndk_path / 'meta/platforms.json'
|
||||
if platforms_map_file.exists():
|
||||
with open(platforms_map_file, 'r') as platforms_map_file_handle:
|
||||
platforms_map_file_json = json.load(platforms_map_file_handle)
|
||||
platforms_map_aliases = platforms_map_file_json['aliases']
|
||||
elif validated_android_platforms:
|
||||
# Revisions before 19 does not have a mapping file for API versions, they fall back to the previous one
|
||||
# So we need to make a mapping file that does the same
|
||||
platforms_map_aliases = {}
|
||||
validated_android_platforms.sort()
|
||||
max_supported_api_number = int(ANDROID_PLATFORM_PATTERN.search(validated_android_platforms[-1]).group(2))
|
||||
for validated_android_platform in validated_android_platforms:
|
||||
current_api_version = int(ANDROID_PLATFORM_PATTERN.search(validated_android_platform).group(2))
|
||||
next_api_version = current_api_version + 1
|
||||
while f'android-{next_api_version}' not in validated_android_platforms and next_api_version <= max_supported_api_number:
|
||||
platforms_map_aliases[str(next_api_version)] = current_api_version
|
||||
next_api_version += 1
|
||||
|
||||
# Go through the aliases and add to the validated platforms if it is mapped to an existing platform
|
||||
for alias_key, alias_value in platforms_map_aliases.items():
|
||||
if not ANDROID_PLATFORM_PATTERN.search(f'android-{alias_key}'):
|
||||
# Skip any non android-XX (XX = number) aliases
|
||||
continue
|
||||
aliased_platform_key = f'android-{alias_value}'
|
||||
if aliased_platform_key in validated_android_platforms:
|
||||
validated_android_platforms.append(f'android-{alias_key}')
|
||||
|
||||
if not validated_android_platforms:
|
||||
raise common.LmbrCmdError(f"Invalid Android NDK path {str(check_android_ndk_path)}")
|
||||
|
||||
# Verify the ndk platform against the ndk path
|
||||
android_ndk_platform_name = f'android-{android_ndk_platform_number}'
|
||||
if android_ndk_platform_name not in validated_android_platforms:
|
||||
raise common.LmbrCmdError(f"Android NDK platform {android_ndk_platform_name} is not a valid for the Android NDK located under '{str(check_android_ndk_path)}'")
|
||||
|
||||
return android_ndk_platform_number, check_android_ndk_path
|
||||
|
||||
|
||||
ADB_TARGET = 'adb.exe' if platform.system() == 'Windows' else 'adb'
|
||||
|
||||
|
||||
def resolve_adb_tool(android_sdk_path):
|
||||
@@ -1528,9 +1353,16 @@ def resolve_adb_tool(android_sdk_path):
|
||||
if isinstance(android_sdk_path, str):
|
||||
android_sdk_path = pathlib.Path(android_sdk_path)
|
||||
|
||||
check_adb_target = android_sdk_path / 'platform-tools' / ADB_TARGET
|
||||
if not check_adb_target.exists():
|
||||
raise common.LmbrCmdError(f"Invalid Android SDK path '{str(android_sdk_path)}': Unable to locate '{ADB_TARGET}'.")
|
||||
file_found = False
|
||||
for executable_path_ext in common.PLATFORM_EXECUTABLE_EXTENSIONS:
|
||||
check_adb_target = android_sdk_path / 'platform-tools' / f'adb{executable_path_ext}'
|
||||
if check_adb_target.is_file():
|
||||
file_found = True
|
||||
break
|
||||
|
||||
if not file_found:
|
||||
raise common.LmbrCmdError(f"Invalid Android SDK path '{str(android_sdk_path)}': Unable to locate 'adb'.")
|
||||
|
||||
return check_adb_target
|
||||
|
||||
|
||||
@@ -1633,3 +1465,196 @@ class AdbTool(common.CommandLineExec):
|
||||
else:
|
||||
adb_params = arguments
|
||||
return super().popen(adb_params, cwd)
|
||||
|
||||
|
||||
class AndroidGradlePluginInfo(object):
|
||||
|
||||
def __init__(self, android_gradle_plugin_version):
|
||||
|
||||
if android_gradle_plugin_version not in ANDROID_GRADLE_PLUGIN_COMPATIBILITY_MAP.keys():
|
||||
raise common.LmbrCmdError(f"Android Gradle Plugin version {android_gradle_plugin_version} is not supported. "
|
||||
f"Only the following version(s) are supported: {','.join(ANDROID_GRADLE_PLUGIN_COMPATIBILITY_MAP.keys())}")
|
||||
|
||||
details = ANDROID_GRADLE_PLUGIN_COMPATIBILITY_MAP[android_gradle_plugin_version]
|
||||
self.default_sdk_build_tools_version = LooseVersion(details.get('sdk_build'))
|
||||
|
||||
self.default_ndk_version = LooseVersion(details.get('default_ndk'))
|
||||
|
||||
self.min_gradle_version = LooseVersion(details.get('min_gradle_version'))
|
||||
|
||||
self.min_cmake_version = LooseVersion(details.get('min_cmake_version'))
|
||||
|
||||
max_cmake_version_number = details.get('max_cmake_version')
|
||||
self.max_cmake_version = None if max_cmake_version_number is None else LooseVersion(max_cmake_version_number)
|
||||
|
||||
|
||||
class AndroidSDKResolver(object):
|
||||
"""
|
||||
Class that manages the Android SDK tool to validate, install packages (e.g. built tools, sdk platforms, ndk, etc)
|
||||
"""
|
||||
|
||||
class InstalledPackage(object):
|
||||
def __init__(self, installed_package_components):
|
||||
assert len(installed_package_components) == 4, '4 sections expected for installed package components (path, version, description, location)'
|
||||
self.path = installed_package_components[0]
|
||||
self.version = LooseVersion(installed_package_components[1])
|
||||
self.description = installed_package_components[2]
|
||||
self.location = installed_package_components[3]
|
||||
|
||||
class AvailablePackage(object):
|
||||
def __init__(self, available_package_components):
|
||||
assert len(available_package_components) == 3, '3 sections expected for installed package components (path, version, description)'
|
||||
self.path = available_package_components[0]
|
||||
self.version = LooseVersion(available_package_components[1])
|
||||
self.description = available_package_components[2]
|
||||
|
||||
class AvailableUpdate(object):
|
||||
def __init__(self, available_update_components):
|
||||
assert len(available_update_components) == 3, '3 sections expected for installed package components (path, version, available)'
|
||||
self.path = available_update_components[0]
|
||||
self.version = LooseVersion(available_update_components[1])
|
||||
self.available = available_update_components[2]
|
||||
|
||||
def __init__(self, android_sdk_path):
|
||||
|
||||
self.android_sdk_path = android_sdk_path or os.environ.get(ANDROID_SDK_ENV_NAME)
|
||||
if not self.android_sdk_path:
|
||||
raise common.LmbrCmdError(f"Android SDK path not set or it was not passed into the command to generate the android project")
|
||||
if not os.path.isdir(self.android_sdk_path):
|
||||
raise common.LmbrCmdError(f"Android SDK path {self.android_sdk_path} is not valid")
|
||||
if platform.system() == 'Windows':
|
||||
self.sdk_manager_path = pathlib.Path(self.android_sdk_path) / 'tools' / 'bin' / 'sdkmanager.bat'
|
||||
else:
|
||||
raise common.LmbrCmdError(f"This tool is not supported on the current platform {platform.system()}")
|
||||
if not self.sdk_manager_path.is_file():
|
||||
raise common.LmbrCmdError(f"Android SDK path {self.android_sdk_path} is not valid or complete. Missing {self.sdk_manager_path}")
|
||||
|
||||
self.sdk_manager = common.CommandLineExec(str(self.sdk_manager_path.resolve()))
|
||||
|
||||
self.installed_packages = {}
|
||||
self.available_packages = {}
|
||||
self.available_updates = {}
|
||||
self.refresh_sdk_installation()
|
||||
|
||||
def refresh_sdk_installation(self):
|
||||
"""
|
||||
Utilize the sdk_manager command line tool from the Android SDK to collect / refresh the list of
|
||||
installed, available, and updateable packages that are managed by the android SDK.
|
||||
"""
|
||||
self.installed_packages = {}
|
||||
self.available_packages = {}
|
||||
self.available_updates = {}
|
||||
|
||||
def _factory_installed_package(package_map, item_components):
|
||||
package_map[item_components[0]] = AndroidSDKResolver.InstalledPackage(item_components)
|
||||
|
||||
def _factory_available_package(package_map, item_components):
|
||||
package_map[item_components[0]] = AndroidSDKResolver.AvailablePackage(item_components)
|
||||
|
||||
def _factory_available_update(package_map, item_components):
|
||||
package_map[item_components[0]] = AndroidSDKResolver.AvailableUpdate(item_components)
|
||||
|
||||
# Use the SDK manager to collect the available and installed packages
|
||||
result_code, result_stdout, result_stderr = self.sdk_manager.exec(['--list'], capture_stdout=True, suppress_stderr=True)
|
||||
|
||||
current_append_map = None
|
||||
current_item_factory = None
|
||||
for package_item in result_stdout.split('\n'):
|
||||
package_item_stripped = package_item.strip()
|
||||
if not package_item_stripped:
|
||||
continue
|
||||
if '|' not in package_item_stripped:
|
||||
if package_item_stripped.upper() == 'INSTALLED PACKAGES:':
|
||||
current_append_map = self.installed_packages
|
||||
current_item_factory = _factory_installed_package
|
||||
elif package_item_stripped.upper() == 'AVAILABLE PACKAGES:':
|
||||
current_append_map = self.available_packages
|
||||
current_item_factory = _factory_available_package
|
||||
elif package_item_stripped.upper() == 'AVAILABLE UPDATES:':
|
||||
current_append_map = self.available_updates
|
||||
current_item_factory = _factory_available_update
|
||||
else:
|
||||
current_append_map = None
|
||||
current_item_factory = None
|
||||
continue
|
||||
item_parts = [split.strip() for split in package_item_stripped.split('|')]
|
||||
if len(item_parts) < 3:
|
||||
continue
|
||||
elif item_parts[1].upper() in ('VERSION', 'INSTALLED', '-------'):
|
||||
continue
|
||||
elif current_append_map is None:
|
||||
continue
|
||||
if current_append_map is not None and current_item_factory is not None:
|
||||
current_item_factory(current_append_map, item_parts)
|
||||
|
||||
def is_package_installed(self, search_package_path):
|
||||
"""
|
||||
Check if a package path to see if its a package that is installed. The path can use wildcard '*'s
|
||||
The function will return a list of the results that match the package paths, ordered by the newest version first
|
||||
"""
|
||||
def _package_sort(package):
|
||||
return package.version
|
||||
package_detail_result_list = []
|
||||
for installed_package_path, installed_package_details in self.installed_packages.items():
|
||||
if fnmatch.fnmatch(installed_package_path, search_package_path):
|
||||
package_detail_result_list.append(installed_package_details)
|
||||
package_detail_result_list.sort(reverse=True, key=_package_sort)
|
||||
return package_detail_result_list
|
||||
|
||||
def is_package_available(self, search_package_path):
|
||||
"""
|
||||
Check if a package path to see if its an available package to install. The path can use wildcard '*'s
|
||||
The function will return a list of the results that match the package paths, ordered by the newest version first
|
||||
"""
|
||||
def _package_sort(package):
|
||||
return package.version
|
||||
package_detail_result_list = []
|
||||
for available_package_path, available_package_details in self.available_packages.items():
|
||||
if fnmatch.fnmatch(available_package_path, search_package_path):
|
||||
package_detail_result_list.append(available_package_details)
|
||||
package_detail_result_list.sort(reverse=True, key=_package_sort)
|
||||
return package_detail_result_list
|
||||
|
||||
def install_package(self, package_install_path, package_description):
|
||||
"""
|
||||
Install a package based on the path of an available android sdk package
|
||||
"""
|
||||
|
||||
# Skip installation if the package is already installed
|
||||
package_result_list = self.is_package_installed(package_install_path)
|
||||
if package_result_list:
|
||||
installed_package_detail = package_result_list[0]
|
||||
logging.info(f"{installed_package_detail.description} (version {installed_package_detail.version}) Detected")
|
||||
return installed_package_detail
|
||||
|
||||
# Make sure the package name is available
|
||||
package_result_list = self.is_package_available(package_install_path)
|
||||
if not package_result_list:
|
||||
raise common.LmbrCmdError(f"Invalid Android SDK Package {package_description}: Bad package path {package_install_path}")
|
||||
|
||||
# Reverse sort and pick the first item, which should be the latest (if the install path contains wildcards)
|
||||
def _available_sort(item):
|
||||
return item.path
|
||||
|
||||
package_result_list.sort(reverse=True, key=_available_sort)
|
||||
|
||||
available_package_to_install = package_result_list[0] # For multiple hits, resolve to the first item which will be the latest version
|
||||
|
||||
# Perform the package installation
|
||||
logging.info(f"Installing {available_package_to_install.description} ...")
|
||||
result_code, result_stdout, result_stderr = self.sdk_manager.exec(['--install', available_package_to_install.path], capture_stdout=True, suppress_stderr=True)
|
||||
if result_code != 0:
|
||||
raise common.LmbrCmdError(f"Error installing package {available_package_to_install.path}: \n{result_stderr}")
|
||||
|
||||
# Refresh the tracked SDK Contents
|
||||
self.refresh_sdk_installation()
|
||||
|
||||
# Get the package details to verify
|
||||
package_result_list = self.is_package_installed(package_install_path)
|
||||
if package_result_list:
|
||||
installed_package_detail = package_result_list[0]
|
||||
logging.info(f"{installed_package_detail.description} (version {installed_package_detail.version}) Installed")
|
||||
return installed_package_detail
|
||||
else:
|
||||
raise common.LmbrCmdError(f"Error installing package {available_package_to_install.path}: \n{result_stderr}")
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ from cmake.Tools import common
|
||||
from cmake.Tools.Platform.Android import android_support
|
||||
|
||||
GRADLE_ARGUMENT_NAME = '--gradle-install-path'
|
||||
GRADLE_MIN_VERSION = LooseVersion('4.10.1')
|
||||
GRADLE_MIN_VERSION = LooseVersion('6.5')
|
||||
GRADLE_MAX_VERSION = LooseVersion('7.0.0')
|
||||
GRADLE_VERSION_REGEX = re.compile(r"Gradle\s(\d+.\d+.?\d*)")
|
||||
GRADLE_EXECUTABLE = 'gradle.bat' if platform.system() == 'Windows' else 'gradle'
|
||||
@@ -48,9 +48,9 @@ def verify_gradle(override_gradle_path=None):
|
||||
|
||||
|
||||
CMAKE_ARGUMENT_NAME = '--cmake-install-path'
|
||||
CMAKE_MIN_VERSION = LooseVersion('3.17.0')
|
||||
CMAKE_MIN_VERSION = LooseVersion('3.19.0')
|
||||
CMAKE_VERSION_REGEX = re.compile(r'cmake version (\d+.\d+.?\d*)')
|
||||
CMAKE_EXECUTABLE = 'cmake.exe' if platform.system() == 'Windows' else 'cmake'
|
||||
CMAKE_EXECUTABLE = 'cmake'
|
||||
|
||||
|
||||
def verify_cmake(override_cmake_path=None):
|
||||
@@ -69,7 +69,7 @@ def verify_cmake(override_cmake_path=None):
|
||||
|
||||
NINJA_ARGUMENT_NAME = '--ninja-install-path'
|
||||
NINJA_VERSION_REGEX = re.compile(r'(\d+.\d+.?\d*)')
|
||||
NINJA_EXECUTABLE = 'ninja.exe' if platform.system() == 'Windows' else 'ninja'
|
||||
NINJA_EXECUTABLE = 'ninja'
|
||||
|
||||
|
||||
def verify_ninja(override_ninja_path=None):
|
||||
@@ -78,7 +78,7 @@ def verify_ninja(override_ninja_path=None):
|
||||
"""
|
||||
return common.verify_tool(override_tool_path=override_ninja_path,
|
||||
tool_name='ninja',
|
||||
tool_filename='ninja.exe' if platform.system() == 'Windows' else 'ninja',
|
||||
tool_filename='ninja',
|
||||
argument_name=NINJA_ARGUMENT_NAME,
|
||||
tool_version_argument='--version',
|
||||
tool_version_regex=NINJA_VERSION_REGEX,
|
||||
@@ -103,13 +103,21 @@ def build_optional_signing_profile(store_file, store_password, key_alias, key_pa
|
||||
|
||||
|
||||
ANDROID_SDK_ARGUMENT_NAME = '--android-sdk-path'
|
||||
ANDROID_SDK_PLATFORM_ARGUMENT_NAME = '--android-sdk-version'
|
||||
ANDROID_SDK_PLATFORM_ARGUMENT_NAME = '--android-sdk-platform'
|
||||
ANDROID_SDK_PREFERRED_TOOL_VER = '--android-sdk-build-tool-version'
|
||||
|
||||
ANDROID_NATIVE_API_LEVEL = '--android-native-api-level'
|
||||
|
||||
|
||||
MIN_ANDROID_SDK_PLATFORM = 28 # The minimum platform/api level that is supported for the SDK Platform
|
||||
MIN_NATIVE_API_LEVEL = 24 # The minimum Native API level that is supported for the NDK
|
||||
|
||||
|
||||
ANDROID_NDK_ARGUMENT_NAME = '--android-ndk-path'
|
||||
ANDROID_NDK_PLATFORM_ARGUMENT_NAME = '--android-ndk-version'
|
||||
|
||||
ANDROID_GRADLE_PLUGIN_ARGUMENT_NAME = '--gradle-plugin-version'
|
||||
ANDROID_GRADLE_MIN_PLUGIN_VERSION = LooseVersion("4.2.0")
|
||||
|
||||
# Constants for asset-related options for APK generation
|
||||
INCLUDE_APK_ASSETS_ARGUMENT_NAME = "--include-apk-assets"
|
||||
ASSET_MODE_ARGUMENT_NAME = "--asset-mode"
|
||||
@@ -147,6 +155,7 @@ def main(args):
|
||||
|
||||
parser = argparse.ArgumentParser(description="Prepare the android studio subfolder")
|
||||
|
||||
# Required Arguments
|
||||
parser.add_argument('--engine-root',
|
||||
help='The path to the engine root. Defaults to the current working directory.',
|
||||
default=os.getcwd())
|
||||
@@ -160,32 +169,42 @@ def main(args):
|
||||
help='The path to the 3rd Party root directory',
|
||||
required=True)
|
||||
|
||||
parser.add_argument(ANDROID_NDK_ARGUMENT_NAME,
|
||||
help='The path to the android NDK',
|
||||
required=True)
|
||||
|
||||
parser.add_argument(ANDROID_SDK_ARGUMENT_NAME,
|
||||
help='The path to the android SDK',
|
||||
required=True)
|
||||
|
||||
parser.add_argument(ANDROID_SDK_PLATFORM_ARGUMENT_NAME,
|
||||
help='The android SDK version',
|
||||
parser.add_argument('-g', '--project-path',
|
||||
help='The project path to generate an android project',
|
||||
required=True)
|
||||
|
||||
parser.add_argument(ANDROID_SDK_PLATFORM_ARGUMENT_NAME,
|
||||
help=f'The android SDK platform number version to use for the APK. (Minimum {MIN_ANDROID_SDK_PLATFORM})',
|
||||
type=int,
|
||||
default=-1)
|
||||
|
||||
parser.add_argument(ANDROID_NATIVE_API_LEVEL,
|
||||
help=f'The android native API level to use for the APK. If not set, this will default to the android SDK platform. (Minimum {MIN_ANDROID_SDK_PLATFORM})',
|
||||
type=int,
|
||||
default=-1)
|
||||
|
||||
# Override arguments
|
||||
parser.add_argument(ANDROID_SDK_PREFERRED_TOOL_VER,
|
||||
help='The preferred android sdk build version (i.e. 28.0.3). Will default to the first one detected under the android sdk',
|
||||
default=None,
|
||||
help='The android SDK build tools version.',
|
||||
required=False)
|
||||
|
||||
parser.add_argument(ANDROID_NDK_PLATFORM_ARGUMENT_NAME,
|
||||
help='The android NDK version',
|
||||
required=True)
|
||||
required=False)
|
||||
|
||||
parser.add_argument(GRADLE_ARGUMENT_NAME,
|
||||
help=f'The path to installed gradle. The version of gradle must fall in between {str(GRADLE_MIN_VERSION)} and {str(GRADLE_MAX_VERSION)}.',
|
||||
default=None,
|
||||
required=False)
|
||||
|
||||
parser.add_argument(ANDROID_GRADLE_PLUGIN_ARGUMENT_NAME,
|
||||
help=f'The version of the android gradle plugin to use. Defaults to the minimum version ({ANDROID_GRADLE_MIN_PLUGIN_VERSION})',
|
||||
default=str(ANDROID_GRADLE_MIN_PLUGIN_VERSION))
|
||||
|
||||
parser.add_argument(CMAKE_ARGUMENT_NAME,
|
||||
help=f'The path to cmake build tool if not installed on the system path. The version of cmake must be at least version {str(CMAKE_MIN_VERSION)}.',
|
||||
default=None,
|
||||
@@ -196,9 +215,6 @@ def main(args):
|
||||
default=None,
|
||||
required=False)
|
||||
|
||||
parser.add_argument('-g', '--project-path',
|
||||
help='The project path to generate an android project')
|
||||
|
||||
# Asset Options
|
||||
parser.add_argument(INCLUDE_APK_ASSETS_ARGUMENT_NAME,
|
||||
action='store_true',
|
||||
@@ -207,11 +223,11 @@ def main(args):
|
||||
parser.add_argument(ASSET_MODE_ARGUMENT_NAME,
|
||||
choices=ALL_ASSET_MODES,
|
||||
default=ASSET_MODE_LOOSE,
|
||||
help='Asset Mode (vfs|pak|loose) to use when including assets into the APK')
|
||||
help=f'Asset Mode (vfs|pak|loose) to use when including assets into the APK. (Defaults to {ASSET_MODE_LOOSE})')
|
||||
|
||||
parser.add_argument(ASSET_TYPE_ARGUMENT_NAME,
|
||||
default=DEFAULT_ASSET_TYPE,
|
||||
help='Asset Type to use when including assets into the APK')
|
||||
help=f'Asset Type to use when including assets into the APK. (Defaults to {DEFAULT_ASSET_TYPE})')
|
||||
|
||||
parser.add_argument('--debug',
|
||||
action='store_true',
|
||||
@@ -260,16 +276,81 @@ def main(args):
|
||||
ninja_version, override_ninja_path = verify_ninja(override_ninja_path=parsed_args.get_argument(NINJA_ARGUMENT_NAME))
|
||||
logging.info("Detected Ninja version %s", str(ninja_version))
|
||||
|
||||
# Verify the android sdk path and sdk version
|
||||
verified_android_sdk_platform, verified_android_sdk_path, android_sdk_build_tool_ver = android_support.verify_android_sdk(android_sdk_platform=parsed_args.get_argument(ANDROID_SDK_PLATFORM_ARGUMENT_NAME),
|
||||
argument_name=ANDROID_SDK_ARGUMENT_NAME,
|
||||
override_android_sdk_path=parsed_args.get_argument(ANDROID_SDK_ARGUMENT_NAME),
|
||||
preferred_sdk_build_tools_ver=parsed_args.get_argument(ANDROID_SDK_PREFERRED_TOOL_VER))
|
||||
# Get the android sdk platform version to use from the arguments, but also handle the deprecated argument name
|
||||
android_sdk_platform_version = parsed_args.get_argument(ANDROID_SDK_PLATFORM_ARGUMENT_NAME)
|
||||
|
||||
# Verify the android ndk path and ndk version
|
||||
verified_android_ndk_platform, verified_android_ndk_path = android_support.verify_android_ndk(android_ndk_platform=parsed_args.get_argument(ANDROID_NDK_PLATFORM_ARGUMENT_NAME),
|
||||
argument_name=ANDROID_NDK_ARGUMENT_NAME,
|
||||
override_android_ndk_path=parsed_args.get_argument(ANDROID_NDK_ARGUMENT_NAME))
|
||||
# Get the gradle plugin details and validate against the current environment
|
||||
android_gradle_plugin_version = parsed_args.get_argument(ANDROID_GRADLE_PLUGIN_ARGUMENT_NAME)
|
||||
android_gradle_plugin = android_support.AndroidGradlePluginInfo(android_gradle_plugin_version)
|
||||
logging.info(f"Generating Android Gradle Plugin version {android_gradle_plugin_version} based project")
|
||||
|
||||
if gradle_version < android_gradle_plugin.min_gradle_version:
|
||||
raise common.LmbrCmdError(f"The current version of gradle ({gradle_version}) does not satisfy the minimum version "
|
||||
f"({android_gradle_plugin.min_gradle_version}) needed for the android gradle plugin "
|
||||
f"({android_gradle_plugin_version}). Please upgrade your gradle.")
|
||||
if cmake_version < android_gradle_plugin.min_cmake_version:
|
||||
raise common.LmbrCmdError(f"The current version of cmake ({cmake_version}) does not satisfy the minimum version "
|
||||
f"({android_gradle_plugin.min_cmake_version}) needed for the android gradle plugin "
|
||||
f"({android_gradle_plugin_version}). Please upgrade your cmake.")
|
||||
if android_gradle_plugin.max_cmake_version and cmake_version > android_gradle_plugin.max_cmake_version:
|
||||
raise common.LmbrCmdError(f"The current version of cmake ({cmake_version}) exceeds the maximum version "
|
||||
f"({android_gradle_plugin.max_cmake_version}) of the android gradle plugin "
|
||||
f"({android_gradle_plugin_version}).")
|
||||
|
||||
# Use the SDK Resolver to make sure the build tools and ndk
|
||||
android_sdk = android_support.AndroidSDKResolver(android_sdk_path=parsed_args.get_argument(ANDROID_SDK_ARGUMENT_NAME))
|
||||
|
||||
# If no SDK platform is provided, check for any installed one
|
||||
if android_sdk_platform_version < 0:
|
||||
android_sdk_platform_version = MIN_ANDROID_SDK_PLATFORM
|
||||
installed_android_sdk_platforms = android_sdk.is_package_installed('platforms;*')
|
||||
if installed_android_sdk_platforms:
|
||||
# If there are installed platforms, check the most recent one
|
||||
latest_platform_version = -1
|
||||
for installed_android_sdk_platform in installed_android_sdk_platforms:
|
||||
platform_number_match = re.match(r'platforms;android-([0-9]*)', installed_android_sdk_platform.path)
|
||||
if not platform_number_match:
|
||||
continue
|
||||
check_platform_version = int(platform_number_match.group(1))
|
||||
if check_platform_version > latest_platform_version:
|
||||
latest_platform_version = check_platform_version
|
||||
if latest_platform_version >= MIN_ANDROID_SDK_PLATFORM:
|
||||
android_sdk_platform_version = latest_platform_version
|
||||
else:
|
||||
if android_sdk_platform_version < MIN_ANDROID_SDK_PLATFORM:
|
||||
raise common.LmbrCmdError(f"Invalid argument for {ANDROID_SDK_PLATFORM_ARGUMENT_NAME} ({android_sdk_platform_version}). Must be greater than the minimum value supported {MIN_ANDROID_SDK_PLATFORM}.")
|
||||
|
||||
# Get the android native api level from the arguments. Default to the sdk platform version if not provided
|
||||
android_native_api_level = parsed_args.get_argument(ANDROID_NATIVE_API_LEVEL)
|
||||
if android_native_api_level < 0:
|
||||
android_native_api_level = android_sdk_platform_version
|
||||
else:
|
||||
if android_native_api_level < MIN_NATIVE_API_LEVEL:
|
||||
raise common.LmbrCmdError(f"Invalid argument for {ANDROID_NATIVE_API_LEVEL} ({android_native_api_level}). Must be greater than the minimum value supported {MIN_NATIVE_API_LEVEL}.")
|
||||
|
||||
# Check and make sure that the requested sdk platform exists, download if necessary
|
||||
platform_package_name = f"platforms;android-{android_sdk_platform_version}"
|
||||
android_sdk.install_package(package_install_path=platform_package_name,
|
||||
package_description=f'Android SDK Platform {android_sdk_platform_version}')
|
||||
|
||||
# Make sure we have the extra android packages "market_apk_expansion" and "market_licensing" which is needed by the APK
|
||||
android_sdk.install_package(package_install_path='extras;google;market_apk_expansion',
|
||||
package_description='Google APK Expansion Library')
|
||||
|
||||
android_sdk.install_package(package_install_path='extras;google;market_licensing',
|
||||
package_description='Google Play Licensing Library')
|
||||
|
||||
# Install either the requested SDK build tools or the default one for the android gradle plugin version
|
||||
build_tools_version = parsed_args.get_argument(ANDROID_SDK_PREFERRED_TOOL_VER) or android_gradle_plugin.default_sdk_build_tools_version
|
||||
build_tools_package_name = f'build-tools;{build_tools_version}'
|
||||
build_tools_package = android_sdk.install_package(package_install_path=build_tools_package_name,
|
||||
package_description='Android SDK Build Tools')
|
||||
|
||||
# Install either the requested NDK version or the default one for the android gradle plugin version
|
||||
android_ndk_version = parsed_args.get_argument(ANDROID_NDK_PLATFORM_ARGUMENT_NAME) or android_gradle_plugin.default_ndk_version
|
||||
android_ndk_package_name = f'ndk;{android_ndk_version}'
|
||||
android_ndk_package = android_sdk.install_package(package_install_path=android_ndk_package_name,
|
||||
package_description='Android NDK')
|
||||
|
||||
# Verify the engine root path and project path
|
||||
verified_project_path, verified_engine_root = common.verify_project_and_engine_root(project_root=parsed_args.project_path,
|
||||
@@ -277,10 +358,9 @@ def main(args):
|
||||
is_test_project = parsed_args.unit_test
|
||||
|
||||
# Verify the 3rd Party Root Path
|
||||
third_party_path = pathlib.Path(parsed_args.third_party_path) / '3rdParty.txt'
|
||||
if not third_party_path.is_file():
|
||||
raise common.LmbrCmdError("Invalid --third-party-path '{}'. Make sure it exists and contains "
|
||||
"3rdParty.txt".format(parsed_args.third_party_path),
|
||||
third_party_path = pathlib.Path(parsed_args.third_party_path)
|
||||
if not third_party_path.is_dir():
|
||||
raise common.LmbrCmdError(f"Invalid --third-party-path '{parsed_args.third_party_path}'.",
|
||||
common.ERROR_CODE_INVALID_PARAMETER)
|
||||
third_party_path = third_party_path.parent
|
||||
|
||||
@@ -293,23 +373,23 @@ def main(args):
|
||||
|
||||
logging.debug("Engine Root : %s", str(verified_engine_root.resolve()))
|
||||
logging.debug("Build Path : %s", str(build_dir.resolve()))
|
||||
logging.debug("Android NDK Path : %s", str(verified_android_ndk_path.resolve()))
|
||||
logging.debug("Android SDK Path : %s", str(verified_android_sdk_path.resolve()))
|
||||
|
||||
# Prepare the generator and execute
|
||||
generator = android_support.AndroidProjectGenerator(engine_root=verified_engine_root,
|
||||
project_path=verified_project_path,
|
||||
build_dir=build_dir,
|
||||
android_sdk_path=verified_android_sdk_path,
|
||||
android_ndk_path=verified_android_ndk_path,
|
||||
android_sdk_version=verified_android_sdk_platform,
|
||||
android_ndk_platform=verified_android_ndk_platform,
|
||||
android_sdk_path=android_sdk.android_sdk_path,
|
||||
build_tool=build_tools_package,
|
||||
android_sdk_platform=android_sdk_platform_version,
|
||||
android_native_api_level=android_native_api_level,
|
||||
android_ndk=android_ndk_package,
|
||||
project_path=verified_project_path,
|
||||
third_party_path=third_party_path,
|
||||
cmake_version=cmake_version,
|
||||
override_cmake_path=override_cmake_path,
|
||||
override_gradle_path=override_gradle_path,
|
||||
gradle_version=gradle_version,
|
||||
gradle_plugin_version=android_gradle_plugin_version,
|
||||
override_ninja_path=override_ninja_path,
|
||||
android_sdk_build_tool_version=android_sdk_build_tool_ver,
|
||||
include_assets_in_apk=parsed_args.get_argument(INCLUDE_APK_ASSETS_ARGUMENT_NAME),
|
||||
asset_mode=parsed_args.get_argument(ASSET_MODE_ARGUMENT_NAME),
|
||||
asset_type=parsed_args.get_argument(ASSET_TYPE_ARGUMENT_NAME),
|
||||
|
||||
@@ -170,117 +170,3 @@ def test_verify_ninja(tmpdir, from_override, version_str, expected_result):
|
||||
finally:
|
||||
subprocess.check_output = orig_check_output
|
||||
|
||||
|
||||
TEST_VALIDATE_VERSION_MIN = 19
|
||||
TEST_VALIDATE_VERSION_MAX = 21
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input, expected", [
|
||||
pytest.param('20', 20),
|
||||
pytest.param('android-20', 20),
|
||||
pytest.param('bad-21', "android-'XX'"),
|
||||
pytest.param('10', "minimum"),
|
||||
pytest.param('30', "maximum")
|
||||
]
|
||||
)
|
||||
def test_validate_android_platform_input(test_input, expected):
|
||||
try:
|
||||
result = android_support.validate_android_platform_input(input_android_platform=test_input,
|
||||
platform_variable_type='test',
|
||||
min_version=TEST_VALIDATE_VERSION_MIN,
|
||||
max_version=TEST_VALIDATE_VERSION_MAX)
|
||||
assert isinstance(expected, int)
|
||||
assert result == expected
|
||||
except Exception as e:
|
||||
assert expected in str(e)
|
||||
|
||||
|
||||
def test_verify_android_sdk_success(tmpdir):
|
||||
|
||||
test_android_path = 'android_sdk'
|
||||
sdk_version_number = 28
|
||||
sdk_version = f'android-{sdk_version_number}'
|
||||
|
||||
tmpdir.ensure(f'{test_android_path}/platforms/{sdk_version}/package.xml')
|
||||
|
||||
tmpdir.ensure(f'{test_android_path}/build-tools/28.0.3/package.xml')
|
||||
tmpdir.ensure(f'{test_android_path}/build-tools/29.0.3/package.xml')
|
||||
|
||||
input_sdk_path = tmpdir.join(test_android_path).realpath()
|
||||
argument_name = '--android-sdk'
|
||||
|
||||
requested_build_tool_version = '29.0.3'
|
||||
|
||||
result_sdk_version, result_sdk_path, result_build_tool_version = android_support.verify_android_sdk(android_sdk_platform=sdk_version,
|
||||
argument_name=argument_name,
|
||||
override_android_sdk_path=input_sdk_path,
|
||||
preferred_sdk_build_tools_ver=requested_build_tool_version)
|
||||
assert result_sdk_version == sdk_version_number
|
||||
assert result_sdk_path == input_sdk_path
|
||||
assert result_build_tool_version == requested_build_tool_version
|
||||
|
||||
sdk_version_number_only = str(sdk_version_number)
|
||||
result_sdk_version, result_sdk_path, result_build_tool_version = android_support.verify_android_sdk(android_sdk_platform=sdk_version_number_only,
|
||||
argument_name=argument_name,
|
||||
override_android_sdk_path=input_sdk_path)
|
||||
assert result_sdk_version == sdk_version_number
|
||||
assert result_sdk_path == input_sdk_path
|
||||
assert result_build_tool_version == '28.0.3'
|
||||
|
||||
requested_build_tool_version = '30.0.3'
|
||||
result_sdk_version, result_sdk_path, result_build_tool_version = android_support.verify_android_sdk(android_sdk_platform=sdk_version,
|
||||
argument_name=argument_name,
|
||||
override_android_sdk_path=input_sdk_path,
|
||||
preferred_sdk_build_tools_ver=requested_build_tool_version)
|
||||
assert result_sdk_version == sdk_version_number
|
||||
assert result_sdk_path == input_sdk_path
|
||||
assert result_build_tool_version == '28.0.3'
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"desired_ndk_version_number, available_ndk_revisions, pkg_revision, mappings, expect_error", [
|
||||
pytest.param(21, [21, 22, 24], '15.2.4203891', None, False, id='preNdk19ExactMatch'),
|
||||
pytest.param(23, [21, 22, 24], '15.2.4203891', None, False, id='preNdk19FallbackMatch'),
|
||||
pytest.param(22, [21, 22, 24], '19.2.4203891', {'23': 21}, False, id='postNdk19ExactMatch'),
|
||||
pytest.param(23, [21, 22, 24], '21.2.4203891', {'23': 21}, False, id='postNdk19MappingMatch'),
|
||||
pytest.param(android_support.ANDROID_NDK_MIN_PLATFORM-1, [21, 22, 24], '15.2.4203891', None, True, id='preNdk19BelowMinVer'),
|
||||
pytest.param(android_support.ANDROID_NDK_MAX_PLATFORM+1, [21, 22, 24], '15.2.4203891', None, True, id='preNdk19AboveMaxVer'),
|
||||
pytest.param(25, [21, 22, 24], '19.2.4203891', {'23': 21}, True, id='postNdk19NoMatch')
|
||||
]
|
||||
)
|
||||
def test_verify_android_ndk_success(tmpdir, desired_ndk_version_number, available_ndk_revisions, pkg_revision, mappings, expect_error):
|
||||
|
||||
test_android_path = 'android_ndk'
|
||||
for ndk_number in available_ndk_revisions:
|
||||
tmpdir.ensure(f'{test_android_path}/platforms/android-{ndk_number}/arch-arm64/usr/lib/libc.so')
|
||||
|
||||
tmpdir.ensure(f'{test_android_path}/source.properties')
|
||||
test_ndk_source_properties_file = tmpdir / test_android_path / 'source.properties'
|
||||
test_ndk_source_properties_file.write_text(f'Pkg.Desc = Android NDK\nPkg.Revision = {pkg_revision}\n', encoding='ASCII')
|
||||
|
||||
if mappings:
|
||||
platform_mapping = {
|
||||
# min and max are arbitrary for now since we dont use it during evaluation, but if we do, parameterize it here as well
|
||||
"min": 16, #
|
||||
"max": 29,
|
||||
"aliases": {}
|
||||
}
|
||||
for key, value in mappings.items():
|
||||
platform_mapping['aliases'][key] = value
|
||||
tmpdir.ensure(f'{test_android_path}/meta/platforms.json')
|
||||
platform_mapping_file = tmpdir / test_android_path / 'meta/platforms.json'
|
||||
platform_mapping_file.write_text(json.dumps(platform_mapping), encoding='ASCII')
|
||||
|
||||
input_ndk_path = tmpdir.join(test_android_path).realpath()
|
||||
|
||||
try:
|
||||
android_ndk_platform_number, android_ndk_path = android_support.verify_android_ndk(android_ndk_platform=str(desired_ndk_version_number),
|
||||
argument_name="--android-ndk",
|
||||
override_android_ndk_path=input_ndk_path)
|
||||
assert not expect_error
|
||||
assert android_ndk_platform_number == desired_ndk_version_number
|
||||
assert android_ndk_path == input_ndk_path
|
||||
except Exception:
|
||||
assert expect_error
|
||||
|
||||
|
||||
+30
-7
@@ -55,6 +55,7 @@ ENGINE_ROOT_CHECK_FILE = 'engine.json'
|
||||
HASH_CHUNK_SIZE = 200000
|
||||
|
||||
|
||||
|
||||
class LmbrCmdError(Exception):
|
||||
"""
|
||||
Wrapper class to the general exception class where will absorb and prevent the printing of stack.
|
||||
@@ -244,6 +245,19 @@ def load_template_file(template_file_path, template_env):
|
||||
raise FileNotFoundError(f"Invalid file path. Cannot find template file located at {str(template_file_path)}")
|
||||
|
||||
|
||||
# Determine the possible file extensions for executable files based on the host platform
|
||||
PLATFORM_EXECUTABLE_EXTENSIONS = [''] # Files without extensions are always considered
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
# Windows manages its executable extensions through the %PATHEXT% environment variable
|
||||
path_extensions_str = os.environ.get('PATHEXT', default='.EXE;.COM;.BAT;.CMD')
|
||||
PLATFORM_EXECUTABLE_EXTENSIONS.extend([pathext.lower() for pathext in path_extensions_str.split(';')])
|
||||
elif platform.system() == 'Linux':
|
||||
PLATFORM_EXECUTABLE_EXTENSIONS = ['', '.out']
|
||||
else:
|
||||
PLATFORM_EXECUTABLE_EXTENSIONS = ['']
|
||||
|
||||
|
||||
def verify_tool(override_tool_path, tool_name, tool_filename, argument_name, tool_version_argument, tool_version_regex, min_version, max_version):
|
||||
"""
|
||||
Support method to validate a required system tool needed for the build either through an installed tool in the
|
||||
@@ -270,12 +284,21 @@ def verify_tool(override_tool_path, tool_name, tool_filename, argument_name, too
|
||||
elif not isinstance(override_tool_path, pathlib.Path):
|
||||
raise LmbrCmdError(f"Invalid {tool_name} path argument. '{override_tool_path}' must be a string or Path",
|
||||
ERROR_CODE_INVALID_PARAMETER)
|
||||
check_tool_path = override_tool_path / tool_filename
|
||||
|
||||
if not check_tool_path.is_file():
|
||||
check_tool_path = pathlib.Path(override_tool_path) / 'bin' / tool_filename
|
||||
file_found = False
|
||||
for executable_path_ext in PLATFORM_EXECUTABLE_EXTENSIONS:
|
||||
check_tool_filename = f'{tool_filename}{executable_path_ext}'
|
||||
|
||||
if not check_tool_path.is_file():
|
||||
check_tool_path = override_tool_path / check_tool_filename
|
||||
if check_tool_path.is_file():
|
||||
file_found = True
|
||||
break
|
||||
check_tool_path = override_tool_path / 'bin' / check_tool_filename
|
||||
if check_tool_path.is_file():
|
||||
file_found = True
|
||||
break
|
||||
|
||||
if not file_found:
|
||||
raise LmbrCmdError(f"Invalid {tool_name} path argument. '{override_tool_path}' is not a valid {tool_name} path",
|
||||
ERROR_CODE_INVALID_PARAMETER)
|
||||
resolved_override_tool_path = str(check_tool_path.resolve())
|
||||
@@ -284,7 +307,7 @@ def verify_tool(override_tool_path, tool_name, tool_filename, argument_name, too
|
||||
else:
|
||||
resolved_override_tool_path = None
|
||||
tool_source = tool_name
|
||||
tool_desc = "installed gradle in the system path"
|
||||
tool_desc = f"installed {tool_name} in the system path"
|
||||
|
||||
# Extract the version and verify
|
||||
version_output = subprocess.check_output([tool_source, tool_version_argument],
|
||||
@@ -296,10 +319,10 @@ def verify_tool(override_tool_path, tool_name, tool_filename, argument_name, too
|
||||
result_version = LooseVersion(str(version_match.group(1)).strip())
|
||||
|
||||
if min_version and result_version < min_version:
|
||||
raise LmbrCmdError(f"The {tool_desc} does not meet the minimum version of gradle required ({str(min_version)}).",
|
||||
raise LmbrCmdError(f"The {tool_desc} does not meet the minimum version of {tool_name} required ({str(min_version)}).",
|
||||
ERROR_CODE_ENVIRONMENT_ERROR)
|
||||
elif max_version and result_version > max_version:
|
||||
raise LmbrCmdError(f"The {tool_desc} exceeds maximum version of gradle supported ({str(max_version)}).",
|
||||
raise LmbrCmdError(f"The {tool_desc} exceeds maximum version of {tool_name} supported ({str(max_version)}).",
|
||||
ERROR_CODE_ENVIRONMENT_ERROR)
|
||||
|
||||
return result_version, resolved_override_tool_path
|
||||
|
||||
@@ -141,10 +141,8 @@
|
||||
"COMMAND":"gradle_windows.cmd",
|
||||
"PARAMETERS": {
|
||||
"CONFIGURATION":"profile",
|
||||
"OUTPUT_DIRECTORY":"build\\android_gradle",
|
||||
"OUTPUT_DIRECTORY":"build\\ad_grd",
|
||||
"GAME_PROJECT": "AutomatedTesting",
|
||||
"ANDROID_NDK_PLATFORM": "21",
|
||||
"ANDROID_SDK_PLATFORM": "29",
|
||||
"SIGN_APK": "false",
|
||||
"GRADLE_BUILD_CMD": "build",
|
||||
"ADDITIONAL_GENERATE_ARGS": ""
|
||||
@@ -158,8 +156,6 @@
|
||||
"CONFIGURATION":"profile",
|
||||
"OUTPUT_DIRECTORY":"build\\android_unittest",
|
||||
"GAME_PROJECT": "AutomatedTesting",
|
||||
"ANDROID_NDK_PLATFORM": "21",
|
||||
"ANDROID_SDK_PLATFORM": "29",
|
||||
"SIGN_APK": "true",
|
||||
"GRADLE_BUILD_CMD": "assemble",
|
||||
"ADDITIONAL_GENERATE_ARGS": "--unit-test"
|
||||
|
||||
@@ -17,20 +17,12 @@ IF NOT EXIST "%LY_3RDPARTY_PATH%" (
|
||||
GOTO :error
|
||||
)
|
||||
|
||||
IF NOT EXIST "%GRADLE_HOME%" (
|
||||
IF NOT EXIST "%GRADLE_BUILD_HOME%" (
|
||||
REM This is the default for developers
|
||||
SET GRADLE_HOME=C:\Gradle\gradle-5.6.4
|
||||
SET GRADLE_BUILD_HOME=C:\Gradle\gradle-7.0
|
||||
)
|
||||
IF NOT EXIST "%GRADLE_HOME%" (
|
||||
ECHO [ci_build] FAIL: GRADLE_HOME=%GRADLE_HOME%
|
||||
GOTO :error
|
||||
)
|
||||
|
||||
IF NOT EXIST "%CMAKE_HOME%" (
|
||||
SET CMAKE_HOME=%LY_3RDPARTY_PATH%/CMake/3.19.1/Windows/
|
||||
)
|
||||
IF NOT EXIST "%CMAKE_HOME%" (
|
||||
ECHO [ci_build] FAIL: CMAKE_HOME=%CMAKE_HOME%
|
||||
IF NOT EXIST "%GRADLE_BUILD_HOME%" (
|
||||
ECHO [ci_build] FAIL: GRADLE_BUILD_HOME=%GRADLE_BUILD_HOME%
|
||||
GOTO :error
|
||||
)
|
||||
|
||||
@@ -50,20 +42,9 @@ ECHO Ninja wasnt in the call path, add the value set by LY_NINJA_PATH
|
||||
SET PATH=%PATH%;%LY_NINJA_PATH%
|
||||
|
||||
:ninja_on_path
|
||||
IF NOT EXIST "%LY_ANDROID_SDK%" (
|
||||
SET LY_ANDROID_SDK=!LY_3RDPARTY_PATH!/android-sdk/platform-29
|
||||
)
|
||||
IF NOT EXIST "%LY_ANDROID_SDK%" (
|
||||
ECHO [ci_build] FAIL: LY_ANDROID_SDK=!LY_ANDROID_SDK!
|
||||
GOTO :error
|
||||
)
|
||||
|
||||
IF NOT EXIST "%LY_ANDROID_NDK%" (
|
||||
set LY_ANDROID_NDK=!LY_3RDPARTY_PATH!/android-ndk/r21d
|
||||
)
|
||||
IF NOT EXIST "%LY_ANDROID_NDK%" (
|
||||
ECHO [ci_build] LY_ANDROID_NDK=!LY_ANDROID_NDK!
|
||||
GOTO :error
|
||||
IF NOT "%ANDROID_GRADLE_PLUGIN%" == "" (
|
||||
set ANDROID_GRADLE_PLUGIN_OPTION=--gradle-plugin-version=%ANDROID_GRADLE_PLUGIN%
|
||||
)
|
||||
|
||||
IF NOT EXIST %OUTPUT_DIRECTORY% (
|
||||
@@ -154,11 +135,11 @@ IF "%GENERATE_SIGNED_APK%"=="true" (
|
||||
ECHO Using keystore file at %CI_ANDROID_KEYSTORE_FILE_ABS%
|
||||
)
|
||||
|
||||
ECHO [ci_build] %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% --signconfig-store-file %CI_ANDROID_KEYSTORE_FILE_ABS% --signconfig-store-password %CI_ANDROID_KEYSTORE_PASSWORD% --signconfig-key-alias %CI_ANDROID_KEYSTORE_ALIAS% --signconfig-key-password %CI_ANDROID_KEYSTORE_PASSWORD% %OPTIONAL_TEST_FLAG% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
CALL %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% --signconfig-store-file %CI_ANDROID_KEYSTORE_FILE_ABS% --signconfig-store-password %CI_ANDROID_KEYSTORE_PASSWORD% --signconfig-key-alias %CI_ANDROID_KEYSTORE_ALIAS% --signconfig-key-password %CI_ANDROID_KEYSTORE_PASSWORD% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
ECHO [ci_build] %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_BUILD_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-sdk-path=%ANDROID_HOME% %ANDROID_GRADLE_PLUGIN_OPTION% --signconfig-store-file %CI_ANDROID_KEYSTORE_FILE_ABS% --signconfig-store-password %CI_ANDROID_KEYSTORE_PASSWORD% --signconfig-key-alias %CI_ANDROID_KEYSTORE_ALIAS% --signconfig-key-password %CI_ANDROID_KEYSTORE_PASSWORD% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
CALL %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_BUILD_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-sdk-path=%ANDROID_HOME% %ANDROID_GRADLE_PLUGIN_OPTION% --signconfig-store-file %CI_ANDROID_KEYSTORE_FILE_ABS% --signconfig-store-password %CI_ANDROID_KEYSTORE_PASSWORD% --signconfig-key-alias %CI_ANDROID_KEYSTORE_ALIAS% --signconfig-key-password %CI_ANDROID_KEYSTORE_PASSWORD% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
) ELSE (
|
||||
ECHO [ci_build] %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
CALL %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
ECHO [ci_build] %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% %GRADLE_OVERRIDE_OPTION% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% %ANDROID_GRADLE_PLUGIN_OPTION% --android-sdk-path=%ANDROID_HOME% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
CALL %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_BUILD_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% %ANDROID_GRADLE_PLUGIN_OPTION% --android-sdk-path=%ANDROID_HOME% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
|
||||
)
|
||||
|
||||
REM Validate the android project generation
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ENV": {
|
||||
"GRADLE_HOME": "C:/Gradle/gradle-5.6.4",
|
||||
"NODE_LABEL": "windows-047e5cdf",
|
||||
"GRADLE_HOME": "C:/Gradle/gradle-7.0",
|
||||
"NODE_LABEL": "windows-b3c8994f1",
|
||||
"LY_3RDPARTY_PATH": "C:/ly/3rdParty",
|
||||
"TIMEOUT": 30,
|
||||
"WORKSPACE": "D:/workspace",
|
||||
|
||||
Reference in New Issue
Block a user