Support Talos VFX particles

This commit is contained in:
fgnm
2021-01-24 20:56:58 +01:00
parent 59d18a583e
commit a308bc544f
28 changed files with 500 additions and 36 deletions
+1
View File
@@ -1,4 +1,5 @@
[0.0.4]
- Add support to Talos Particles VFX
- Add Sticky Notes feature
- Add GL Profiler in Performance plugin
- Add smooth camera pan
+16
View File
@@ -0,0 +1,16 @@
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main()
{
v_color = a_color;
v_color.a = v_color.a * (256.0/255.0);
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
+1
View File
@@ -97,6 +97,7 @@ dependencies {
implementation project(":hyperlap2d-runtime-libgdx")
implementation project(":h2d-libgdx-spine-extension")
implementation "com.talosvfx:talos-libgdx:$talosVersion"
implementation "space.earlygrey:shapedrawer:$shapedrawerVersion"
implementation "com.rafaskoberg.gdx:typing-label:$typingLabelVersion"
implementation "com.kotcrab.vis:vis-ui:$visuiVersion"
+2 -1
View File
@@ -5,4 +5,5 @@ ashleyVersion = 1.7.3
spineVersion = 3.8.55.1
visuiVersion = 1.4.9-SNAPSHOT
typingLabelVersion = 1.2.0
shapedrawerVersion = 2.4.0
shapedrawerVersion = 2.4.0
talosVersion = 1.3.1
@@ -104,6 +104,7 @@ public class BootstrapCommand extends SimpleCommand {
facade.registerCommand(MsgAPI.ACTION_DELETE_LIBRARY_ACTION, DeleteLibraryAction::new);
facade.registerCommand(MsgAPI.ACTION_EXPORT_LIBRARY_ITEM, ExportLibraryItemCommand::new);
facade.registerCommand(MsgAPI.ACTION_DELETE_PARTICLE_EFFECT, DeleteParticleEffect::new);
facade.registerCommand(MsgAPI.ACTION_DELETE_TALOS_VFX, DeleteTalosVFX::new);
facade.registerCommand(MsgAPI.ACTION_DELETE_SPINE_ANIMATION_RESOURCE, DeleteSpineAnimation::new);
facade.registerCommand(MsgAPI.ACTION_DELETE_SPRITE_ANIMATION_RESOURCE, DeleteSpriteAnimation::new);
@@ -124,6 +124,11 @@ public class PasteItemsCommand extends EntityModifyRevertibleCommand {
Sandbox.getInstance().getEngine().addEntity(child);
entities.add(child);
}
for (int i = 0; i < compositeVO.sTalosVFX.size(); i++) {
Entity child = factory.createEntity(parentEntity, compositeVO.sTalosVFX.get(i));
Sandbox.getInstance().getEngine().addEntity(child);
entities.add(child);
}
for (int i = 0; i < compositeVO.sLights.size(); i++) {
Entity child = factory.createEntity(parentEntity, compositeVO.sLights.get(i));
Sandbox.getInstance().getEngine().addEntity(child);
@@ -0,0 +1,77 @@
package games.rednblack.editor.controller.commands.resource;
import com.badlogic.ashley.core.Entity;
import games.rednblack.editor.renderer.components.additional.TalosComponent;
import games.rednblack.editor.renderer.data.CompositeItemVO;
import games.rednblack.editor.renderer.data.SceneVO;
import games.rednblack.editor.renderer.data.TalosVO;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
import games.rednblack.editor.utils.runtime.EntityUtils;
import java.util.ArrayList;
import java.util.function.Consumer;
public class DeleteTalosVFX extends DeleteResourceCommand {
private static final String CLASS_NAME = "games.rednblack.editor.controller.commands.resource.DeleteTalosVFX";
public static final String DONE = CLASS_NAME + "DONE";
private final ArrayList<Entity> entityList = new ArrayList<>();
private final ArrayList<TalosVO> tmpParticleEffectList = new ArrayList<>();
@Override
protected String confirmDialogTitle() {
return "Delete Talos VFX";
}
@Override
public void doAction() {
String particleName = notification.getBody();
if (projectManager.deleteTalosVFX(particleName)) {
deleteEntitiesWithParticleEffects(sandbox.getRootEntity(), particleName); // delete entities from scene
deleteAllItemsWithParticleName(particleName);
projectManager.loadProjectData(projectManager.getCurrentProjectPath());
sendNotification(DONE, particleName);
SceneVO vo = sandbox.sceneVoFromItems();
projectManager.saveCurrentProject(vo);
} else {
cancel();
}
}
private void deleteAllItemsWithParticleName(String name) {
for (CompositeItemVO compositeItemVO : libraryItems.values()) {
deleteAllParticles(compositeItemVO, name);
}
}
private void deleteAllParticles(CompositeItemVO compositeItemVO, String name) {
Consumer<CompositeItemVO> action = (rootItemVo) -> getParticles(rootItemVo, name);
EntityUtils.applyActionRecursivelyOnLibraryItems(compositeItemVO, action);
}
private void getParticles(CompositeItemVO compositeItemVO, String name) {
if (compositeItemVO.composite != null && compositeItemVO.composite.sTalosVFX.size() != 0) {
ArrayList<TalosVO> particleEffectList = compositeItemVO.composite.sTalosVFX;
for (TalosVO particleEffectVO : particleEffectList) {
if (particleEffectVO.particleName.equals(name)) {
tmpParticleEffectList.add(particleEffectVO);
}
}
particleEffectList.removeAll(tmpParticleEffectList);
tmpParticleEffectList.clear();
}
}
private void deleteEntitiesWithParticleEffects(Entity rootEntity, String particleName) {
entityList.clear();
Consumer<Entity> action = (root) -> {
TalosComponent particleComponent = ComponentRetriever.get(root, TalosComponent.class);
if (particleComponent != null && particleComponent.particleName.equals(particleName)) {
entityList.add(root);
}
};
EntityUtils.applyActionRecursivelyOnEntities(rootEntity, action);
EntityUtils.removeEntities(entityList);
}
}
@@ -4,8 +4,14 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
import com.badlogic.gdx.graphics.g2d.ParticleEmitter;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonWriter;
import com.talosvfx.talos.runtime.ParticleEffectDescriptor;
import com.talosvfx.talos.runtime.ParticleEmitterDescriptor;
import com.talosvfx.talos.runtime.modules.AbstractModule;
import com.talosvfx.talos.runtime.modules.ShadedSpriteModule;
import com.talosvfx.talos.runtime.modules.TextureModule;
import games.rednblack.editor.controller.commands.NonRevertibleCommand;
import games.rednblack.editor.proxy.ProjectManager;
import games.rednblack.editor.proxy.ResourceManager;
@@ -150,6 +156,26 @@ public class ExportLibraryItemCommand extends NonRevertibleCommand {
}
}
for (TalosVO imageVO : compositeVO.sTalosVFX) {
File fileSrc = new File(currentProjectPath + ProjectManager.TALOS_VFX_DIR_PATH + File.separator + imageVO.particleName);
FileUtils.copyFileToDirectory(fileSrc, tmpDir);
exportMapperVO.mapper.add(new ExportedAsset(ImportUtils.TYPE_TALOS_VFX, fileSrc.getName()));
ParticleEffectDescriptor particleEffect = resourceManager.getProjectTalosList().get(imageVO.particleName);
for (ParticleEmitterDescriptor emitter : new Array.ArrayIterator<>(particleEffect.emitterModuleGraphs)) {
for (AbstractModule module : new Array.ArrayIterator<>(emitter.getModules())) {
if (module instanceof TextureModule) {
String path = ((TextureModule) module).regionName + ".png";
File f = new File(currentProjectPath + ProjectManager.IMAGE_DIR_PATH + File.separator + path);
FileUtils.copyFileToDirectory(f, tmpDir);
} else if (module instanceof ShadedSpriteModule) {
String path = ((ShadedSpriteModule) module).shdrFileName;
File f = new File(currentProjectPath + ProjectManager.TALOS_VFX_DIR_PATH + File.separator + path);
FileUtils.copyFileToDirectory(f, tmpDir);
}
}
}
}
for (CompositeItemVO compositeItemVO : compositeVO.sComposites) {
exportAllAssets(compositeItemVO.composite, tmpDir);
}
@@ -222,6 +222,29 @@ public class ItemFactory {
return entity;
}
public boolean tryCreateTalosItem(String particleName, Vector2 position) {
Entity entity = createTalosItem(particleName, position);
/* DimensionsComponent dimensionsComponent = ComponentRetriever.get(entity, DimensionsComponent.class);
float boundBoxSize = 10f;
dimensionsComponent.boundBox = new Rectangle(-boundBoxSize / 2f, -boundBoxSize / 2f, boundBoxSize, boundBoxSize);*/
if(entity == null) return false;
return true;
}
public Entity createTalosItem(String particleName, Vector2 position) {
TalosVO vo = new TalosVO();
vo.particleName = particleName;
if(!setEssentialData(vo, position)) return null;
Entity entity = entityFactory.createEntity(sandbox.getCurrentViewingEntity(), vo);
HyperLap2DFacade.getInstance().sendNotification(MsgAPI.ACTION_CREATE_ITEM, entity);
return entity;
}
public Entity createLabel(TextTool textSettings, Vector2 position) {
LabelVO vo = new LabelVO();
if(!setEssentialData(vo, position)) return null;
@@ -20,15 +20,16 @@ package games.rednblack.editor.proxy;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.tools.texturepacker.TexturePacker;
import com.badlogic.gdx.tools.texturepacker.TexturePacker.Settings;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import com.esotericsoftware.spine.SkeletonData;
import com.esotericsoftware.spine.SkeletonJson;
import com.esotericsoftware.spine.utils.SpineUtils;
import com.badlogic.gdx.utils.ObjectSet;
import com.kotcrab.vis.ui.util.dialog.Dialogs;
import com.talosvfx.talos.runtime.ParticleEmitterDescriptor;
import com.talosvfx.talos.runtime.modules.AbstractModule;
import com.talosvfx.talos.runtime.modules.ShadedSpriteModule;
import com.talosvfx.talos.runtime.serialization.ExportData;
import games.rednblack.editor.HyperLap2DFacade;
import games.rednblack.editor.data.manager.PreferencesManager;
import games.rednblack.editor.data.migrations.ProjectVersionMigrator;
@@ -38,6 +39,7 @@ import games.rednblack.editor.renderer.utils.Version;
import games.rednblack.editor.utils.AssetImporter;
import games.rednblack.editor.utils.HyperLap2DUtils;
import games.rednblack.editor.utils.ZipUtils;
import games.rednblack.editor.utils.runtime.TalosResources;
import games.rednblack.editor.view.menu.HyperLap2DMenuBar;
import games.rednblack.editor.view.stage.Sandbox;
import games.rednblack.editor.view.ui.dialog.SettingsDialog;
@@ -84,6 +86,7 @@ public class ProjectManager extends Proxy {
public static final String SPINE_DIR_PATH = "assets/orig/spine-animations";
public static final String SPRITE_DIR_PATH = "assets/orig/sprite-animations";
public static final String PARTICLE_DIR_PATH = "assets/orig/particles";
public static final String TALOS_VFX_DIR_PATH = "assets/orig/talos-vfx";
public static final String SHADER_DIR_PATH = "assets/shaders";
public ProjectVO currentProjectVO;
@@ -648,6 +651,7 @@ public class ProjectManager extends Proxy {
if (file.exists()) {
imgs.add(new FileHandle(file));
} else {
imgs.clear();
return false;
}
}
@@ -656,6 +660,7 @@ public class ProjectManager extends Proxy {
if (file.exists()) {
imgs.add(new FileHandle(file));
} else {
imgs.clear();
return false;
}
}
@@ -721,6 +726,124 @@ public class ProjectManager extends Proxy {
executor.shutdown();
}
private boolean addTalosImages(TalosResources talosResources, FileHandle fileHandle, Array<FileHandle> imgs) {
try {
Array<String> resources = talosResources.metadata.resources;
for (String res : resources) {
res += ".png";
File file = new File(FilenameUtils.getFullPath(fileHandle.path()) + res);
if (file.exists()) {
imgs.add(new FileHandle(file));
} else {
Dialogs.showErrorDialog(Sandbox.getInstance().getUIStage(),
"\nCould not find " + file.getName() + ".\nCheck if the file exists in the same directory.").padBottom(20).pack();
imgs.clear();
return false;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
private boolean addTalosRes(TalosResources talosResources, FileHandle fileHandle, Array<FileHandle> imgs) {
try {
for (TalosResources.Emitter emitter : talosResources.emitters) {
for (TalosResources.Module module : emitter.modules) {
if (module.get("shdrAssetName") != null) {
String assetName = module.get("shdrAssetName").toString();
File file = new File(FilenameUtils.getFullPath(fileHandle.path()) + assetName);
if (file.exists()) {
imgs.add(new FileHandle(file));
} else {
Dialogs.showErrorDialog(Sandbox.getInstance().getUIStage(),
"\nCould not find " + file.getName() + ".\nCheck if the file exists in the same directory.").padBottom(20).pack();
imgs.clear();
return false;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public void importTalosIntoProject(final Array<FileHandle> fileHandles, ProgressHandler progressHandler, boolean skipRepack) {
if (fileHandles == null) {
return;
}
Json json = new Json();
json.setIgnoreUnknownFields(true);
ParticleEmitterDescriptor.registerModules();
for (Class clazz: ParticleEmitterDescriptor.registeredModules) {
json.addClassTag(clazz.getSimpleName(), TalosResources.Module.class);
}
final String targetPath = currentProjectPath + "/assets/orig/talos-vfx";
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
Array<FileHandle> images = new Array<>();
Array<FileHandle> assetsRes = new Array<>();
for (FileHandle fileHandle : new Array.ArrayIterator<>(fileHandles)) {
if (!fileHandle.isDirectory() && fileHandle.exists()) {
try {
TalosResources talosResources = json.fromJson(TalosResources.class, fileHandle);
//copy images
boolean allImagesFound = addTalosImages(talosResources, fileHandle, images);
if (allImagesFound) {
boolean allAssetFound = addTalosRes(talosResources, fileHandle, assetsRes);
if (allAssetFound) {
// copy the fileHandle
String newName = fileHandle.name();
File target = new File(targetPath + "/" + newName);
FileUtils.copyFile(fileHandle.file(), target);
}
}
} catch (IllegalArgumentException e) {
System.out.println("Error importing particles.");
throw e;
} catch (IOException e) {
System.out.println("Error importing particles.");
e.printStackTrace();
}
}
}
if (images.size > 0) {
copyImageFilesForAllResolutionsIntoProject(images, false, progressHandler);
}
if (assetsRes.size > 0) {
for (FileHandle fileHandle : assetsRes) {
try {
String newName = fileHandle.name();
File target = new File(targetPath + "/" + newName);
FileUtils.copyFile(fileHandle.file(), target);
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (!skipRepack) {
ResolutionManager resolutionManager = facade.retrieveProxy(ResolutionManager.NAME);
resolutionManager.rePackProjectImagesForAllResolutionsSync();
}
});
executor.execute(() -> {
progressHandler.progressChanged(100);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressHandler.progressComplete();
});
executor.shutdown();
}
public void importAtlasesIntoProject(final Array<FileHandle> files, ProgressHandler progressHandler) {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
@@ -955,6 +1078,10 @@ public class ProjectManager extends Proxy {
if (!currentProjectVO.projectMainExportPath.isEmpty()) {
exportParticles(currentProjectVO.projectMainExportPath);
}
exportTalosVFX(defaultBuildPath);
if (!currentProjectVO.projectMainExportPath.isEmpty()) {
exportTalosVFX(currentProjectVO.projectMainExportPath);
}
exportShaders(defaultBuildPath);
if (!currentProjectVO.projectMainExportPath.isEmpty()) {
exportShaders(currentProjectVO.projectMainExportPath);
@@ -1007,6 +1134,18 @@ public class ProjectManager extends Proxy {
}
}
private void exportTalosVFX(String targetPath) {
String srcPath = currentProjectPath + "/assets/orig";
FileHandle origDirectoryHandle = Gdx.files.absolute(srcPath);
FileHandle particlesDirectory = origDirectoryHandle.child("talos-vfx");
File fileTarget = new File(targetPath + "/" + particlesDirectory.name());
try {
FileUtils.copyDirectory(particlesDirectory.file(), fileTarget);
} catch (IOException e) {
e.printStackTrace();
}
}
private void exportFonts(String targetPath) {
String srcPath = currentProjectPath + "/assets/orig";
FileHandle origDirectoryHandle = Gdx.files.absolute(srcPath);
@@ -1370,6 +1509,12 @@ public class ProjectManager extends Proxy {
return (new File(filePath)).delete();
}
public boolean deleteTalosVFX(String particleName) {
String particlePath = currentProjectPath + File.separator + TALOS_VFX_DIR_PATH + File.separator;
String filePath = particlePath + particleName;
return (new File(filePath)).delete();
}
private boolean deleteSpineAnimation(String resolutionName, String spineName) {
String spinePath = currentProjectPath + "/assets/" + resolutionName + "/spine-animations" + File.separator;
String filePath = spinePath + spineName;
@@ -14,6 +14,11 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.*;
import com.badlogic.gdx.utils.ObjectMap;
import com.talosvfx.talos.runtime.ParticleEffectDescriptor;
import com.talosvfx.talos.runtime.ParticleEffectInstance;
import com.talosvfx.talos.runtime.assets.AtlasAssetProvider;
import com.talosvfx.talos.runtime.utils.ShaderDescriptor;
import games.rednblack.editor.renderer.data.*;
import org.apache.commons.io.FileUtils;
@@ -43,6 +48,7 @@ public class ResourceManager extends Proxy implements IResourceRetriever {
public static final String NAME = TAG;
private final HashMap<String, ParticleEffect> particleEffects = new HashMap<>(1);
private final HashMap<String, ParticleEffectDescriptor> talosVFXs = new HashMap<>(1);
private TextureAtlas currentProjectAtlas;
private final HashMap<String, SpineAnimData> spineAnimAtlases = new HashMap<>();
@@ -96,6 +102,10 @@ public class ResourceManager extends Proxy implements IResourceRetriever {
return new ParticleEffect(particleEffects.get(name));
}
@Override
public ParticleEffectDescriptor getTalosVFX(String name) {
return talosVFXs.get(name);
}
@Override
public TextureAtlas getSkeletonAtlas(String animationName) {
@@ -163,6 +173,7 @@ public class ResourceManager extends Proxy implements IResourceRetriever {
loadCurrentProjectAssets(projectPath + "/assets/" + curResolution + "/pack/pack.atlas");
loadCurrentProjectSkin(projectPath + "/assets/orig/styles");
loadCurrentProjectParticles(projectPath + "/assets/orig/particles");
loadCurrentProjectTalosVFXs(projectPath + "/assets/orig/talos-vfx");
loadCurrentProjectSpineAnimations(projectPath + "/assets/", curResolution);
loadCurrentProjectSpriteAnimations(projectPath + "/assets/", curResolution);
loadCurrentProjectBitmapFonts(projectPath, curResolution);
@@ -181,9 +192,41 @@ public class ResourceManager extends Proxy implements IResourceRetriever {
particleEffect.load(Gdx.files.internal(file.getAbsolutePath()), currentProjectAtlas, "");
particleEffects.put(filename, particleEffect);
}
}
private void loadCurrentProjectTalosVFXs(String path) {
talosVFXs.clear();
talosShaderPath = path;
FileHandle sourceDir = new FileHandle(path);
for (FileHandle entry : sourceDir.list()) {
File file = entry.file();
String filename = file.getName();
if (file.isDirectory() || filename.endsWith(".DS_Store") || filename.endsWith("shdr")) continue;
AtlasAssetProvider assetProvider = new AtlasAssetProvider(currentProjectAtlas);
assetProvider.setAssetHandler(ShaderDescriptor.class, this::findShaderDescriptorOnLoad);
ParticleEffectDescriptor effectDescriptor = new ParticleEffectDescriptor();
effectDescriptor.setAssetProvider(assetProvider);
effectDescriptor.load(Gdx.files.internal(file.getAbsolutePath()));
talosVFXs.put(filename, effectDescriptor);
}
}
private ObjectMap<String, ShaderDescriptor> shaderDescriptorObjectMap = new ObjectMap<>();
private String talosShaderPath;
private ShaderDescriptor findShaderDescriptorOnLoad (String assetName) {
ShaderDescriptor asset = shaderDescriptorObjectMap.get(assetName);
if (asset == null) {
//Look in all paths, and hopefully load the requested asset, or fail (crash)
final FileHandle file = new FileHandle(talosShaderPath + File.separator + assetName);
asset = new ShaderDescriptor();
if (file.exists()) {
asset.setData(file.readString());
}
}
return asset;
}
private void loadCurrentProjectSpineAnimations(String path, String curResolution) {
spineAnimAtlases.clear();
@@ -408,6 +451,10 @@ public class ResourceManager extends Proxy implements IResourceRetriever {
return particleEffects;
}
public HashMap<String, ParticleEffectDescriptor> getProjectTalosList() {
return talosVFXs;
}
@Override
public ResolutionEntryVO getLoadedResolution() {
if(packResolutionName.equals("orig")) {
@@ -90,6 +90,9 @@ public class AssetImporter {
case ImportUtils.TYPE_PARTICLE_EFFECT:
projectManager.importParticlesIntoProject(files, progressHandler, skipRepack);
break;
case ImportUtils.TYPE_TALOS_VFX:
projectManager.importTalosIntoProject(files, progressHandler, skipRepack);
break;
case ImportUtils.TYPE_SPINE_ANIMATION:
projectManager.importSpineAnimationsIntoProject(files, progressHandler);
break;
@@ -25,6 +25,7 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import games.rednblack.editor.renderer.components.DimensionsComponent;
import games.rednblack.editor.renderer.components.TransformComponent;
import games.rednblack.editor.renderer.components.additional.TalosComponent;
import games.rednblack.editor.renderer.components.light.LightObjectComponent;
import games.rednblack.editor.renderer.components.particle.ParticleComponent;
import games.rednblack.editor.renderer.utils.ComponentRetriever;
@@ -80,7 +81,8 @@ public class EntityBounds extends Rectangle {
height = dimensionsComponent.boundBox.height;
}
if (ComponentRetriever.get(entity, ParticleComponent.class) != null) {
if (ComponentRetriever.get(entity, ParticleComponent.class) != null
|| ComponentRetriever.get(entity, TalosComponent.class) != null) {
width = dimensionsComponent.boundBox.width;
height = dimensionsComponent.boundBox.height;
dimensionsComponent.width = width;
@@ -51,6 +51,7 @@ public class ImportUtils {
public static final int TYPE_SHADER = 10;
public static final int TYPE_HYPERLAP2D_LIBRARY = 11;
public static final int TYPE_HYPERLAP2D_INTERNAL_LIBRARY = 12;
public static final int TYPE_TALOS_VFX = 13;
private final ArrayList<Integer> supportedTypes = new ArrayList<>();
private final FileTypeFilter fileTypeFilter;
@@ -61,6 +62,7 @@ public class ImportUtils {
supportedTypes.add(TYPE_SPRITE_ANIMATION_ATLAS);
supportedTypes.add(TYPE_SPINE_ANIMATION);
supportedTypes.add(TYPE_PARTICLE_EFFECT);
supportedTypes.add(TYPE_TALOS_VFX);
supportedTypes.add(TYPE_SHADER);
supportedTypes.add(TYPE_HYPERLAP2D_LIBRARY);
// TODO: not supported yet
@@ -71,7 +73,7 @@ public class ImportUtils {
fileTypeFilter.addRule("All Supported (*.png, *.atlas, *.p, *.json, *.vert, *.frag, *.h2dlib)", "png", "atlas", "p", "json", "vert", "frag", "h2dlib");
fileTypeFilter.addRule("PNG File (*.png)", "png");
fileTypeFilter.addRule("Sprite Animation Atlas File (*.atlas)", "atlas");
fileTypeFilter.addRule("Particle Effect (*.p)", "p");
fileTypeFilter.addRule("libGDX/Talos Particle Effect (*.p)", "p");
fileTypeFilter.addRule("Spine Animation (*.json)", "json");
fileTypeFilter.addRule("Shader (*.vert, *.frag)", "vert", "frag");
fileTypeFilter.addRule("HyperLap2D Library (*.h2dlib)", "h2dlib");
@@ -180,12 +182,10 @@ public class ImportUtils {
return type;
}
System.out.println("is spine?");
// checking for spine animation
if (contents.contains("\"skeleton\":{") || contents.contains("\"skeleton\": {") || contents.contains("{\"bones\":[")) {
type = TYPE_SPINE_ANIMATION;
System.out.println("is spine");
return type;
}
@@ -195,6 +195,11 @@ public class ImportUtils {
return type;
}
// checking for particle effect
if (contents.contains("emitters")) {
type = TYPE_TALOS_VFX;
return type;
}
} catch (IOException ignore) {
}
@@ -266,6 +271,10 @@ public class ImportUtils {
dir = ProjectManager.PARTICLE_DIR_PATH;
ext = "p";
break;
case ImportUtils.TYPE_TALOS_VFX:
dir = ProjectManager.TALOS_VFX_DIR_PATH;
ext = "p";
break;
case ImportUtils.TYPE_SPINE_ANIMATION:
dir = ProjectManager.SPINE_DIR_PATH;
ext = "json";
@@ -338,6 +338,10 @@ public class EntityUtils {
ParticleEffectVO vo = json.fromJson(ParticleEffectVO.class, jsonString);
return factory.createEntity(parent, vo);
}
if(entityType == EntityFactory.TALOS_TYPE) {
TalosVO vo = json.fromJson(TalosVO.class, jsonString);
return factory.createEntity(parent, vo);
}
if(entityType == EntityFactory.SPRITE_TYPE) {
SpriteAnimationVO vo = json.fromJson(SpriteAnimationVO.class, jsonString);
return factory.createEntity(parent, vo);
@@ -385,6 +389,11 @@ public class EntityUtils {
vo.loadFromEntity(entity);
return json.toJson(vo);
}
if(entityType == EntityFactory.TALOS_TYPE) {
TalosVO vo = new TalosVO();
vo.loadFromEntity(entity);
return json.toJson(vo);
}
if(entityType == EntityFactory.SPRITE_TYPE) {
SpriteAnimationVO vo = new SpriteAnimationVO();
vo.loadFromEntity(entity);
@@ -437,6 +446,11 @@ public class EntityUtils {
vo.loadFromEntity(entity);
holderComposite.sParticleEffects.add(vo);
}
if(entityType == EntityFactory.TALOS_TYPE) {
TalosVO vo = new TalosVO();
vo.loadFromEntity(entity);
holderComposite.sTalosVFX.add(vo);
}
if(entityType == EntityFactory.SPRITE_TYPE) {
SpriteAnimationVO vo = new SpriteAnimationVO();
vo.loadFromEntity(entity);
@@ -0,0 +1,24 @@
package games.rednblack.editor.utils.runtime;
import com.badlogic.gdx.utils.Array;
import java.util.HashMap;
public class TalosResources {
public Metadata metadata = new Metadata();
public Array<Emitter> emitters = new Array<>();
public static class Metadata {
public Array<String> resources = new Array<>();
}
public static class Emitter {
public Array<Module> modules = new Array<>();
}
public static class Module extends HashMap<String, Object> {
}
}
@@ -54,6 +54,7 @@ public class UIDropDownMenu extends H2DPopupMenu {
actionNames.put(MsgAPI.ACTION_DELETE_IMAGE_RESOURCE, "Delete");
actionNames.put(MsgAPI.ACTION_DELETE_LIBRARY_ITEM, "Delete");
actionNames.put(MsgAPI.ACTION_DELETE_PARTICLE_EFFECT, "Delete");
actionNames.put(MsgAPI.ACTION_DELETE_TALOS_VFX, "Delete");
actionNames.put(MsgAPI.ACTION_DELETE_LIBRARY_ACTION, "Delete");
actionNames.put(MsgAPI.ACTION_DELETE_SPRITE_ANIMATION_RESOURCE, "Delete");
actionNames.put(MsgAPI.ACTION_DELETE_SPINE_ANIMATION_RESOURCE, "Delete");
@@ -51,6 +51,7 @@ public class UIDropDownMenuMediator extends Mediator<UIDropDownMenu> {
public static final Integer POLYGON_VERTEX_ACTION_SET = 10;
public static final Integer ORIGIN_POINT_ACTION_SET = 11;
public static final Integer LIBRARY_ACTION_ACTION_SET = 12;
public static final Integer TALOS_ACTION_SET = 13;
private Sandbox sandbox;
@@ -92,6 +93,9 @@ public class UIDropDownMenuMediator extends Mediator<UIDropDownMenu> {
actionSets.put(PARTICLE_ACTION_SET, new Array<>());
actionSets.get(PARTICLE_ACTION_SET).add(MsgAPI.ACTION_DELETE_PARTICLE_EFFECT);
actionSets.put(TALOS_ACTION_SET, new Array<>());
actionSets.get(TALOS_ACTION_SET).add(MsgAPI.ACTION_DELETE_TALOS_VFX);
actionSets.put(ITEMS_ACTIONS_SET, new Array<>());
actionSets.get(ITEMS_ACTIONS_SET).add(MsgAPI.ACTION_CUT);
actionSets.get(ITEMS_ACTIONS_SET).add(MsgAPI.ACTION_COPY);
@@ -124,6 +128,7 @@ public class UIDropDownMenuMediator extends Mediator<UIDropDownMenu> {
UIResourcesBoxMediator.SPRITE_ANIMATION_RIGHT_CLICK,
UIResourcesBoxMediator.LIBRARY_ITEM_RIGHT_CLICK,
UIResourcesBoxMediator.PARTICLE_EFFECT_RIGHT_CLICK,
UIResourcesBoxMediator.TALOS_VFX_RIGHT_CLICK,
UIResourcesBoxMediator.LIBRARY_ACTION_RIGHT_CLICK,
RulersUI.RIGHT_CLICK_RULER,
PolygonTool.MANUAL_VERTEX_POSITION,
@@ -181,6 +186,9 @@ public class UIDropDownMenuMediator extends Mediator<UIDropDownMenu> {
case UIResourcesBoxMediator.PARTICLE_EFFECT_RIGHT_CLICK:
showPopup(PARTICLE_ACTION_SET, notification.getBody());
break;
case UIResourcesBoxMediator.TALOS_VFX_RIGHT_CLICK:
showPopup(TALOS_ACTION_SET, notification.getBody());
break;
case RulersUI.RIGHT_CLICK_RULER:
showPopup(RULER_RESOURCE_ACTION_SET, notification.getBody());
break;
@@ -37,16 +37,17 @@ public class UIResourcesBoxMediator extends PanelMediator<UIResourcesBox> {
private static final String TAG = UIResourcesBoxMediator.class.getCanonicalName();
public static final String NAME = TAG;
private static final String PREFIX = "games.rednblack.editor.view.ui.box";
private static final String PREFIX = "games.rednblack.editor.view.ui.box.UIResourcesBoxMediator";
public static final String IMAGE_RIGHT_CLICK = "IMAGE_RIGHT_CLICK";
public static final String SPINE_ANIMATION_RIGHT_CLICK = "SPINE_ANIMATION_RIGHT_CLICK";
public static final String SPRITE_ANIMATION_RIGHT_CLICK = "SPRITE_ANIMATION_RIGHT_CLICK";
public static final String LIBRARY_ITEM_RIGHT_CLICK = "LIBRARY_ITEM_RIGHT_CLICK";
public static final String PARTICLE_EFFECT_RIGHT_CLICK = "PARTICLE_EFFECT_RIGHT_CLICK";
public static final String LIBRARY_ACTION_RIGHT_CLICK = "LIBRARY_ACTION_RIGHT_CLICK";
public static final String IMAGE_RIGHT_CLICK = PREFIX + ".IMAGE_RIGHT_CLICK";
public static final String SPINE_ANIMATION_RIGHT_CLICK = PREFIX + ".SPINE_ANIMATION_RIGHT_CLICK";
public static final String SPRITE_ANIMATION_RIGHT_CLICK = PREFIX + ".SPRITE_ANIMATION_RIGHT_CLICK";
public static final String LIBRARY_ITEM_RIGHT_CLICK = PREFIX + ".LIBRARY_ITEM_RIGHT_CLICK";
public static final String PARTICLE_EFFECT_RIGHT_CLICK = PREFIX + ".PARTICLE_EFFECT_RIGHT_CLICK";
public static final String TALOS_VFX_RIGHT_CLICK = PREFIX + ".TALOS_VFX_RIGHT_CLICK";
public static final String LIBRARY_ACTION_RIGHT_CLICK = PREFIX + ".LIBRARY_ACTION_RIGHT_CLICK";
public Array<DragAndDrop.Target> customTargets = new Array<DragAndDrop.Target>();
public Array<DragAndDrop.Target> customTargets = new Array<>();
@Override
public void onRegister() {
@@ -77,7 +77,6 @@ public class UIAnimationsTabMediator extends UIResourcesTabMediator<UIAnimations
@Override
protected void initList(String searchText) {
animationBoxes.clear();
Sandbox sandbox = Sandbox.getInstance();
ResourceManager resourceManager = facade.retrieveProxy(ResourceManager.NAME);
if (new SpineItemType().getTypeId() == EntityFactory.SPINE_TYPE) {
@@ -18,18 +18,23 @@
package games.rednblack.editor.view.ui.box.resourcespanel;
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import games.rednblack.editor.controller.commands.resource.DeleteParticleEffect;
import games.rednblack.editor.controller.commands.resource.DeleteTalosVFX;
import games.rednblack.editor.factory.ItemFactory;
import games.rednblack.editor.proxy.ResourceManager;
import games.rednblack.editor.view.stage.Sandbox;
import games.rednblack.editor.view.ui.box.resourcespanel.draggable.DraggableResource;
import games.rednblack.editor.view.ui.box.resourcespanel.draggable.DraggableResourceView;
import games.rednblack.editor.view.ui.box.resourcespanel.draggable.list.ParticleEffectResource;
import games.rednblack.editor.view.ui.box.resourcespanel.draggable.list.TalosResource;
import org.apache.commons.lang3.ArrayUtils;
import org.puremvc.java.interfaces.INotification;
import java.util.HashMap;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import java.util.function.BiFunction;
/**
* Created by azakhary on 4/17/2015.
@@ -39,14 +44,18 @@ public class UIParticleEffectsTabMediator extends UIResourcesTabMediator<UIParti
private static final String TAG = UIParticleEffectsTabMediator.class.getCanonicalName();
public static final String NAME = TAG;
private final Array<DraggableResource> particlesList;
public UIParticleEffectsTabMediator() {
super(NAME, new UIParticleEffectsTab());
particlesList = new Array<>();
}
@Override
public String[] listNotificationInterests() {
String[] listNotification = super.listNotificationInterests();
listNotification = ArrayUtils.add(listNotification, DeleteParticleEffect.DONE);
listNotification = ArrayUtils.add(listNotification, DeleteTalosVFX.DONE);
return listNotification;
}
@@ -54,6 +63,7 @@ public class UIParticleEffectsTabMediator extends UIResourcesTabMediator<UIParti
public void handleNotification(INotification notification) {
super.handleNotification(notification);
switch (notification.getName()) {
case DeleteTalosVFX.DONE:
case DeleteParticleEffect.DONE:
initList(viewComponent.searchString);
break;
@@ -64,18 +74,26 @@ public class UIParticleEffectsTabMediator extends UIResourcesTabMediator<UIParti
@Override
protected void initList(String searchText) {
Sandbox sandbox = Sandbox.getInstance();
//HyperLap2DFacade facade = HyperLap2DFacade.getInstance();
particlesList.clear();
ResourceManager resourceManager = facade.retrieveProxy(ResourceManager.NAME);
HashMap<String, ParticleEffect> particles = resourceManager.getProjectParticleList();
Array<DraggableResource> itemArray = new Array<>();
for (String name : particles.keySet()) {
if(!name.contains(searchText))continue;
DraggableResource draggableResource = new DraggableResource(new ParticleEffectResource(name));
draggableResource.setFactoryFunction(ItemFactory.get()::tryCreateParticleItem);
itemArray.add(draggableResource);
createAnimationResources(resourceManager.getProjectTalosList().keySet(), TalosResource.class, ItemFactory.get()::tryCreateTalosItem, searchText);
createAnimationResources(resourceManager.getProjectParticleList().keySet(), ParticleEffectResource.class, ItemFactory.get()::tryCreateParticleItem, searchText);
viewComponent.setItems(particlesList);
}
private void createAnimationResources(Set<String> strings, Class resourceClass, BiFunction<String, Vector2, Boolean> factoryFunction, String searchText) {
for (String animationName : strings) {
if (!animationName.contains(searchText)) continue;
try {
Constructor constructor = resourceClass.getConstructor(String.class);
DraggableResource draggableResource = new DraggableResource((DraggableResourceView) constructor.newInstance(animationName));
draggableResource.setFactoryFunction(factoryFunction);
particlesList.add(draggableResource);
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
viewComponent.setItems(itemArray);
}
}
@@ -32,7 +32,6 @@ public class ParticleEffectResource extends ListItemResource {
private final Image payloadImg;
private final ResourcePayloadObject payload;
public ParticleEffectResource(String particleName) {
super(particleName, "particle");
facade = HyperLap2DFacade.getInstance();
@@ -59,5 +58,4 @@ public class ParticleEffectResource extends ListItemResource {
public ResourcePayloadObject getPayloadData() {
return payload;
}
}
@@ -0,0 +1,41 @@
package games.rednblack.editor.view.ui.box.resourcespanel.draggable.list;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import games.rednblack.editor.HyperLap2DFacade;
import games.rednblack.editor.view.ui.box.UIResourcesBoxMediator;
import games.rednblack.h2d.common.ResourcePayloadObject;
public class TalosResource extends ListItemResource {
private final HyperLap2DFacade facade;
private final Image payloadImg;
private final ResourcePayloadObject payload;
public TalosResource(String particleName) {
super(particleName, "particle");
facade = HyperLap2DFacade.getInstance();
payloadImg = new Image(getStyle().resourceOver) {
@Override
public void setScale(float scaleXY) {
//Do not scale
}
};
payloadImg.setScale(2);
payloadImg.getColor().a = .85f;
payload = new ResourcePayloadObject();
payload.name = particleName;
setRightClickEvent(UIResourcesBoxMediator.TALOS_VFX_RIGHT_CLICK, payload.name);
payload.className = getClass().getName();
}
@Override
public Actor getDragActor() {
return payloadImg;
}
@Override
public ResourcePayloadObject getPayloadData() {
return payload;
}
}
@@ -33,6 +33,7 @@ public class FollowerFactory {
return new ImageFollower(entity);
case EntityFactory.LIGHT_TYPE:
return new LightFollower(entity);
case EntityFactory.TALOS_TYPE:
case EntityFactory.PARTICLE_TYPE:
return new ParticleFollower(entity);
case EntityFactory.SPINE_TYPE:
@@ -36,6 +36,7 @@ public class ParticleFollower extends BasicFollower {
public ParticleFollower(Entity entity) {
super(entity);
setTransform(false);
}
@Override
@@ -103,6 +103,7 @@ public class ImportPanel extends UIDraggablePanel {
typeNames.put(ImportUtils.TYPE_TTF_FONT, "TTF Font");
typeNames.put(ImportUtils.TYPE_HYPERLAP2D_LIBRARY, "HyperLap2D Library");
typeNames.put(ImportUtils.TYPE_SHADER, "Shader");
typeNames.put(ImportUtils.TYPE_TALOS_VFX, "Talos VFX");
}
public static class DropBundle {