161 lines
7.4 KiB
Java
161 lines
7.4 KiB
Java
package electrosphere.renderer.ui.components;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.joml.Vector3f;
|
|
|
|
import electrosphere.client.entity.camera.CameraEntityUtils;
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.entity.types.creature.CreatureTemplate;
|
|
import electrosphere.game.data.creature.type.CreatureData;
|
|
import electrosphere.game.data.creature.type.visualattribute.AttributeVariant;
|
|
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
|
|
import electrosphere.net.parser.net.message.CharacterMessage;
|
|
import electrosphere.renderer.actor.Actor;
|
|
import electrosphere.renderer.actor.ActorStaticMorph;
|
|
import electrosphere.renderer.actor.ActorUtils;
|
|
import electrosphere.renderer.ui.elements.ActorPanel;
|
|
import electrosphere.renderer.ui.elements.Button;
|
|
import electrosphere.renderer.ui.elements.Div;
|
|
import electrosphere.renderer.ui.elements.Label;
|
|
import electrosphere.renderer.ui.elements.ScrollableContainer;
|
|
import electrosphere.renderer.ui.elements.Slider;
|
|
import electrosphere.renderer.ui.elements.StringCarousel;
|
|
import electrosphere.renderer.ui.elementtypes.Element;
|
|
import electrosphere.renderer.ui.events.ValueChangeEvent;
|
|
import electrosphere.util.Utilities;
|
|
|
|
/**
|
|
* Panel to customize a character
|
|
*/
|
|
public class CharacterCustomizer {
|
|
|
|
/**
|
|
* Minimum width of the component
|
|
*/
|
|
public static final int MIN_WIDTH = 500;
|
|
|
|
/**
|
|
* Minimum height of the component
|
|
*/
|
|
public static final int MIN_HEIGHT = 500;
|
|
|
|
/**
|
|
* Creates a character customizer panel
|
|
* @param race The race of the character
|
|
* @return The panel component
|
|
*/
|
|
public static Element createCharacterCustomizerPanel(String race){
|
|
//figure out race data
|
|
CreatureData selectedRaceType = Globals.gameConfigCurrent.getCreatureTypeLoader().getType(race);
|
|
|
|
//spawn camera so renderer doesn't crash (once render pipeline is modularized this shouldn't be necessary)
|
|
Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(0,0.3f,1).normalize());
|
|
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
|
|
|
//create actor panel
|
|
Actor characterActor = ActorUtils.createActorFromModelPath(selectedRaceType.getModelPath());
|
|
ActorPanel actorPanel = ActorPanel.create(characterActor);
|
|
actorPanel.setAnimation(selectedRaceType.getIdleData().getAnimation().getNameThirdPerson());
|
|
actorPanel.setPosition(new Vector3f(0,-0.5f,-0.6f));
|
|
actorPanel.setScale(new Vector3f(1.0f));
|
|
|
|
//have to build static morph while looping through attributes
|
|
ActorStaticMorph staticMorph = new ActorStaticMorph();
|
|
|
|
//create creature template
|
|
CreatureTemplate template = CreatureTemplate.create(race);
|
|
|
|
//create scrollable
|
|
ScrollableContainer scrollable = ScrollableContainer.createScrollable();
|
|
scrollable.setMinWidth(MIN_WIDTH);
|
|
scrollable.setMinHeight(MIN_HEIGHT);
|
|
|
|
//create edit controls here
|
|
for(VisualAttribute attribute : selectedRaceType.getVisualAttributes()){
|
|
if(attribute.getType().equals(VisualAttribute.TYPE_BONE)){
|
|
//add label for slider
|
|
Label sliderName = new Label(0.6f);
|
|
sliderName.setText(attribute.getAttributeId());
|
|
sliderName.setMinWidth(200);
|
|
//add a slider
|
|
Slider boneSlider = Slider.createSlider((ValueChangeEvent event) -> {
|
|
if(characterActor.getStaticMorph() != null){
|
|
staticMorph.updateValue(attribute.getSubtype(), attribute.getPrimaryBone(), event.getAsFloat());
|
|
if(attribute.getMirrorBone() != null){
|
|
staticMorph.updateValue(attribute.getSubtype(), attribute.getMirrorBone(), event.getAsFloat());
|
|
}
|
|
template.getAttributeValue(attribute.getAttributeId()).setValue(event.getAsFloat());
|
|
}
|
|
});
|
|
float min = attribute.getMinValue();
|
|
float max = attribute.getMaxValue();
|
|
float defaultValue = min + (max - min)/2.0f;
|
|
boneSlider.setMinimum(min);
|
|
boneSlider.setMaximum(max);
|
|
boneSlider.setValue(defaultValue);
|
|
boneSlider.setMinWidth(200);
|
|
//actually add attributes to static morph
|
|
if(attribute.getPrimaryBone() != null && staticMorph.getBoneTransforms(attribute.getPrimaryBone()) == null){
|
|
staticMorph.initBoneTransforms(attribute.getPrimaryBone());
|
|
}
|
|
if(attribute.getMirrorBone() != null && staticMorph.getBoneTransforms(attribute.getMirrorBone()) == null){
|
|
staticMorph.initBoneTransforms(attribute.getMirrorBone());
|
|
}
|
|
//add attribute to creature template
|
|
template.putAttributeValue(attribute.getAttributeId(), defaultValue);
|
|
|
|
scrollable.addChild(Div.createRow(sliderName,boneSlider));
|
|
} else if(attribute.getType().equals(VisualAttribute.TYPE_REMESH)){
|
|
//add label for carousel
|
|
Label scrollableName = new Label(0.6f);
|
|
scrollableName.setText(attribute.getAttributeId());
|
|
scrollableName.setMinWidth(200);
|
|
//add a carousel
|
|
StringCarousel variantCarousel = StringCarousel.create(
|
|
// attribute.getVariants().stream().filter(variant -> ),
|
|
attribute.getVariants().stream().map(variant -> variant.getId()).collect(Collectors.toList()),
|
|
(ValueChangeEvent event) -> {
|
|
//TODO: implement updating visuals
|
|
template.getAttributeValue(attribute.getAttributeId()).setVariantId(event.getAsString());
|
|
AttributeVariant variant = null;
|
|
for(AttributeVariant variantCurrent : attribute.getVariants()){
|
|
if(variantCurrent.getId().equals(event.getAsString())){
|
|
variant = variantCurrent;
|
|
break;
|
|
}
|
|
}
|
|
if(variant != null){
|
|
Globals.assetManager.addModelPathToQueue(variant.getModel());
|
|
for(String mesh : variant.getMeshes()){
|
|
characterActor.getMeshMask().queueMesh(variant.getModel(), mesh);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
variantCarousel.setMinWidth(200);
|
|
//set the current attrib for the template
|
|
template.putAttributeValue(attribute.getAttributeId(), attribute.getVariants().get(0).getId());
|
|
|
|
scrollable.addChild(Div.createRow(scrollableName,variantCarousel));
|
|
}
|
|
}
|
|
//finally set static morph
|
|
characterActor.setActorStaticMorph(staticMorph);
|
|
|
|
//create layout
|
|
Div rVal = Div.createCol(
|
|
Div.createRow(
|
|
scrollable,
|
|
actorPanel
|
|
),
|
|
Button.createButton("Create", () -> {
|
|
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestCreateCharacterMessage(Utilities.stringify(template)));
|
|
})
|
|
);
|
|
|
|
return rVal;
|
|
}
|
|
|
|
}
|