forked from microsoft/AirSim
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request microsoft#2296 from ironclownfish/texture_swap
Texture swap API
- Loading branch information
Showing
19 changed files
with
198 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file added
BIN
+108 KB
Unreal/Plugins/AirSim/Content/StarterContent/Materials/TextureSwappableMaterial.uasset
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "TextureShuffleActor.h" | ||
|
||
void ATextureShuffleActor::SwapTexture_Implementation(int tex_id, int component_id, int material_id) | ||
{ | ||
if (SwappableTextures.Num() < 1) | ||
return; | ||
|
||
if (!MaterialCacheInitialized) | ||
{ | ||
TArray<UStaticMeshComponent*> components; | ||
GetComponents<UStaticMeshComponent>(components); | ||
NumComponents = components.Num(); | ||
DynamicMaterialInstances.Init(nullptr, components[component_id]->GetNumMaterials()); | ||
MaterialCacheInitialized = true; | ||
} | ||
|
||
if (NumComponents == 0 || DynamicMaterialInstances.Num() == 0) | ||
return; | ||
|
||
tex_id %= SwappableTextures.Num(); | ||
component_id %= NumComponents; | ||
material_id %= DynamicMaterialInstances.Num(); | ||
|
||
if (DynamicMaterialInstances[material_id] == nullptr) | ||
{ | ||
DynamicMaterialInstances[material_id] = UMaterialInstanceDynamic::Create(DynamicMaterial, this); | ||
TArray<UStaticMeshComponent*> components; | ||
GetComponents<UStaticMeshComponent>(components); | ||
components[component_id]->SetMaterial(material_id, DynamicMaterialInstances[material_id]); | ||
} | ||
|
||
DynamicMaterialInstances[material_id]->SetTextureParameterValue("TextureParameter", SwappableTextures[tex_id]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#pragma once | ||
|
||
#include "CoreMinimal.h" | ||
#include "Materials/Material.h" | ||
#include "common/common_utils/Utils.hpp" | ||
#include "common/AirSimSettings.hpp" | ||
#include "Engine/StaticMeshActor.h" | ||
#include "TextureShuffleActor.generated.h" | ||
|
||
|
||
UCLASS() | ||
class AIRSIM_API ATextureShuffleActor : public AStaticMeshActor | ||
{ | ||
GENERATED_BODY() | ||
|
||
protected: | ||
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = TextureShuffle) | ||
UMaterialInterface *DynamicMaterial = nullptr; | ||
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = TextureShuffle) | ||
TArray<UTexture2D*> SwappableTextures; | ||
|
||
public: | ||
|
||
UFUNCTION(BlueprintNativeEvent) | ||
void SwapTexture(int tex_id = 0, int component_id = 0, int material_id = 0); | ||
|
||
private: | ||
bool MaterialCacheInitialized = false; | ||
int NumComponents = -1; | ||
|
||
UPROPERTY() | ||
TArray<UMaterialInstanceDynamic*> DynamicMaterialInstances; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Runtime Texture Swapping | ||
|
||
## How to Make An Actor Retexturable | ||
|
||
To be made texture-swappable, an actor must derive from the parent class TextureShuffleActor. | ||
The parent class can be set via the settings tab in the actor's blueprint. | ||
|
||
![Parent Class](images/tex_shuffle_actor.png) | ||
|
||
After setting the parent class to TextureShuffActor, the object gains the member DynamicMaterial. | ||
DynamicMaterial needs to be set--on all actor instances in the scene--to TextureSwappableMaterial. | ||
Warning: Statically setting the Dynamic Material in the blueprint class may cause rendering errors. It seems to work better to set it on all the actor instances in the scene, using the details panel. | ||
|
||
![TextureSwappableMaterial](images/tex_swap_material.png) | ||
|
||
## How to Define the Set(s) of Textures to Choose From | ||
|
||
Typically, certain subsets of actors will share a set of texture options with each other. (e.g. walls that are part of the same building) | ||
|
||
It's easy to set up these groupings by using Unreal Engine's group editing functionality. | ||
Select all the instances that should have the same texture selection, and add the textures to all of them simultaneously via the Details panel. | ||
Use the same technique to add descriptive tags to groups of actors, which will be used to address them in the API. | ||
|
||
![Group Editing](images/tex_swap_group_editing.png) | ||
|
||
It's ideal to work from larger groupings to smaller groupings, simply deselecting actors to narrow down the grouping as you go, and applying any individual actor properties last. | ||
|
||
![Subset Editing](images/tex_swap_subset.png) | ||
|
||
## How to Swap Textures from the API | ||
|
||
The following API is available in C++ and python. (C++ shown) | ||
|
||
```C++ | ||
std::vector<std::string> simSwapTextures(const std::string& tags, int tex_id); | ||
``` | ||
The string of "," or ", " delimited tags identifies on which actors to perform the swap. | ||
The tex_id indexes the array of textures assigned to each actor undergoing a swap. | ||
The function will return the list of objects which matched the provided tags and had the texture swap perfomed. | ||
If tex_id is out-of-bounds for some object's texture set, it will be taken modulo the number of textures that were available. | ||
Demo (Python): | ||
```Python | ||
import airsim | ||
import time | ||
c = airsim.client.MultirotorClient() | ||
print(c.simSwapTextures("furniture", 0)) | ||
time.sleep(2) | ||
print(c.simSwapTextures("chair", 1)) | ||
time.sleep(2) | ||
print(c.simSwapTextures("table", 1)) | ||
time.sleep(2) | ||
print(c.simSwapTextures("chair, right", 0)) | ||
``` | ||
|
||
Results: | ||
|
||
```bash | ||
['RetexturableChair', 'RetexturableChair2', 'RetexturableTable'] | ||
['RetexturableChair', 'RetexturableChair2'] | ||
['RetexturableTable'] | ||
['RetexturableChair2'] | ||
``` | ||
|
||
![Demo](images/tex_swap_demo.gif) | ||
|
||
Note that in this example, different textures were chosen on each actor for the same index value. |