- add support for selectable material per asset in AssetPacks - add option for cleaning up assets in AssetPack projects git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7798 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
1b14d354d2
commit
3f6f694030
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.assetpack; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import org.w3c.dom.Element; |
||||||
|
import org.w3c.dom.NodeList; |
||||||
|
|
||||||
|
/** |
||||||
|
* Configuration for a single asset item while loading |
||||||
|
* @author normenhansen |
||||||
|
*/ |
||||||
|
public class AssetConfiguration { |
||||||
|
|
||||||
|
private Element assetElement; |
||||||
|
private List<NodeList> variationAssets; |
||||||
|
|
||||||
|
public AssetConfiguration(Element assetElement) { |
||||||
|
this.assetElement = assetElement; |
||||||
|
} |
||||||
|
|
||||||
|
public Element getAssetElement() { |
||||||
|
return assetElement; |
||||||
|
} |
||||||
|
|
||||||
|
public List<NodeList> getVariationAssets() { |
||||||
|
return variationAssets; |
||||||
|
} |
||||||
|
|
||||||
|
public void addVariationAssets(Element variationElement) { |
||||||
|
if (variationAssets == null) { |
||||||
|
variationAssets = new ArrayList<NodeList>(); |
||||||
|
} |
||||||
|
variationAssets.add(variationElement.getElementsByTagName("file")); |
||||||
|
} |
||||||
|
|
||||||
|
public void clearExtraAssets() { |
||||||
|
variationAssets.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
<?xml version="1.1" encoding="UTF-8" ?> |
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo"> |
||||||
|
<Properties> |
||||||
|
<Property name="defaultCloseOperation" type="int" value="2"/> |
||||||
|
</Properties> |
||||||
|
<SyntheticProperties> |
||||||
|
<SyntheticProperty name="formSizePolicy" type="int" value="1"/> |
||||||
|
</SyntheticProperties> |
||||||
|
<AuxValues> |
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/> |
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/> |
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/> |
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/> |
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/> |
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/> |
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/> |
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/> |
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/> |
||||||
|
</AuxValues> |
||||||
|
|
||||||
|
<Layout> |
||||||
|
<DimensionLayout dim="0"> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Group type="102" alignment="1" attributes="0"> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Component id="jButton1" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
<Component id="jScrollPane1" alignment="0" pref="267" max="32767" attributes="0"/> |
||||||
|
</Group> |
||||||
|
</DimensionLayout> |
||||||
|
<DimensionLayout dim="1"> |
||||||
|
<Group type="103" groupAlignment="0" attributes="0"> |
||||||
|
<Group type="102" alignment="1" attributes="0"> |
||||||
|
<Component id="jScrollPane1" pref="192" max="32767" attributes="0"/> |
||||||
|
<EmptySpace max="-2" attributes="0"/> |
||||||
|
<Component id="jButton1" min="-2" max="-2" attributes="0"/> |
||||||
|
</Group> |
||||||
|
</Group> |
||||||
|
</DimensionLayout> |
||||||
|
</Layout> |
||||||
|
<SubComponents> |
||||||
|
<Component class="javax.swing.JButton" name="jButton1"> |
||||||
|
<Properties> |
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> |
||||||
|
<ResourceString bundle="com/jme3/gde/assetpack/Bundle.properties" key="VariationSelection.jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/> |
||||||
|
</Property> |
||||||
|
</Properties> |
||||||
|
<Events> |
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/> |
||||||
|
</Events> |
||||||
|
</Component> |
||||||
|
<Container class="javax.swing.JScrollPane" name="jScrollPane1"> |
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/> |
||||||
|
<SubComponents> |
||||||
|
<Container class="javax.swing.JPanel" name="jPanel1"> |
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"> |
||||||
|
<Property name="axis" type="int" value="3"/> |
||||||
|
</Layout> |
||||||
|
</Container> |
||||||
|
</SubComponents> |
||||||
|
</Container> |
||||||
|
</SubComponents> |
||||||
|
</Form> |
@ -0,0 +1,116 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
|
||||||
|
/* |
||||||
|
* VariationSelection.java |
||||||
|
* |
||||||
|
* Created on 01.07.2011, 17:15:52 |
||||||
|
*/ |
||||||
|
package com.jme3.gde.assetpack; |
||||||
|
|
||||||
|
import com.jme3.gde.assetpack.AssetPackLoader.SelectionEntry; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import javax.swing.JComboBox; |
||||||
|
import javax.swing.JFrame; |
||||||
|
import org.w3c.dom.Element; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @author normenhansen |
||||||
|
*/ |
||||||
|
public class VariationSelection extends javax.swing.JDialog { |
||||||
|
|
||||||
|
List<SelectionEntry> list; |
||||||
|
private boolean canceled = false; |
||||||
|
|
||||||
|
/** Creates new form VariationSelection */ |
||||||
|
public VariationSelection(List<SelectionEntry> list) { |
||||||
|
super(new JFrame(), true); |
||||||
|
this.list = list; |
||||||
|
setLocationRelativeTo(null); |
||||||
|
initComponents(); |
||||||
|
updateView(); |
||||||
|
} |
||||||
|
|
||||||
|
private void updateView() { |
||||||
|
jPanel1.removeAll(); |
||||||
|
for (Iterator<SelectionEntry> it = list.iterator(); it.hasNext();) { |
||||||
|
final SelectionEntry selectionEntry = it.next(); |
||||||
|
final JComboBox box = new JComboBox(); |
||||||
|
for (Element element : selectionEntry.names) { |
||||||
|
box.addItem(element.getAttribute("name")); |
||||||
|
} |
||||||
|
box.addActionListener(new ActionListener() { |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
selectionEntry.setSelected(box.getSelectedIndex()); |
||||||
|
} |
||||||
|
}); |
||||||
|
jPanel1.add(box); |
||||||
|
} |
||||||
|
pack(); |
||||||
|
} |
||||||
|
|
||||||
|
/** This method is called from within the constructor to |
||||||
|
* initialize the form. |
||||||
|
* WARNING: Do NOT modify this code. The content of this method is |
||||||
|
* always regenerated by the Form Editor. |
||||||
|
*/ |
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() { |
||||||
|
|
||||||
|
jButton1 = new javax.swing.JButton(); |
||||||
|
jScrollPane1 = new javax.swing.JScrollPane(); |
||||||
|
jPanel1 = new javax.swing.JPanel(); |
||||||
|
|
||||||
|
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); |
||||||
|
|
||||||
|
jButton1.setText(org.openide.util.NbBundle.getMessage(VariationSelection.class, "VariationSelection.jButton1.text")); // NOI18N
|
||||||
|
jButton1.addActionListener(new java.awt.event.ActionListener() { |
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) { |
||||||
|
jButton1ActionPerformed(evt); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.PAGE_AXIS)); |
||||||
|
jScrollPane1.setViewportView(jPanel1); |
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); |
||||||
|
getContentPane().setLayout(layout); |
||||||
|
layout.setHorizontalGroup( |
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() |
||||||
|
.addContainerGap() |
||||||
|
.addComponent(jButton1)) |
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE) |
||||||
|
); |
||||||
|
layout.setVerticalGroup( |
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() |
||||||
|
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE) |
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
||||||
|
.addComponent(jButton1)) |
||||||
|
); |
||||||
|
|
||||||
|
pack(); |
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
|
||||||
|
setVisible(false); |
||||||
|
}//GEN-LAST:event_jButton1ActionPerformed
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JButton jButton1; |
||||||
|
private javax.swing.JPanel jPanel1; |
||||||
|
private javax.swing.JScrollPane jScrollPane1; |
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
public boolean isCanceled() { |
||||||
|
return canceled; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.assetpack.project.actions; |
||||||
|
|
||||||
|
import com.jme3.gde.assetpack.project.AssetPackProject; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.beans.PropertyChangeListener; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.Logger; |
||||||
|
import javax.swing.Action; |
||||||
|
import org.netbeans.api.progress.ProgressHandle; |
||||||
|
import org.netbeans.api.progress.ProgressHandleFactory; |
||||||
|
import org.openide.filesystems.FileObject; |
||||||
|
import org.openide.util.Exceptions; |
||||||
|
import org.w3c.dom.Element; |
||||||
|
import org.w3c.dom.NodeList; |
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
public final class CleanupProjectAction implements Action { |
||||||
|
|
||||||
|
private final AssetPackProject context; |
||||||
|
|
||||||
|
public CleanupProjectAction(AssetPackProject context) { |
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
|
||||||
|
private void scanFiles(final FileObject folder, final ArrayList<String> paths) { |
||||||
|
FileObject[] children = folder.getChildren(); |
||||||
|
for (FileObject fileObject : children) { |
||||||
|
boolean stay = false; |
||||||
|
if (fileObject.isFolder() && !fileObject.isVirtual()) { |
||||||
|
scanFiles(fileObject, paths); |
||||||
|
stay = true; |
||||||
|
} else if (fileObject.isData()) { |
||||||
|
if ("png".equalsIgnoreCase(fileObject.getExt()) |
||||||
|
|| "jpg".equalsIgnoreCase(fileObject.getExt()) |
||||||
|
|| "dds".equalsIgnoreCase(fileObject.getExt()) |
||||||
|
|| "bmp".equalsIgnoreCase(fileObject.getExt())) { |
||||||
|
for (String path : paths) { |
||||||
|
if (fileObject.getPath().endsWith(path)) { |
||||||
|
stay = true; |
||||||
|
} |
||||||
|
} |
||||||
|
if (!stay) { |
||||||
|
try { |
||||||
|
Logger.getLogger(CleanupProjectAction.class.getName()).log(Level.INFO, "Delete unused file {0}", fileObject); |
||||||
|
fileObject.delete(); |
||||||
|
} catch (IOException ex) { |
||||||
|
Exceptions.printStackTrace(ex); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ArrayList<String> scanProjectFiles(Element elem, ArrayList<String> elements) { |
||||||
|
if (elem.getTagName().equals("file")) { |
||||||
|
// Logger.getLogger(CleanupProjectAction.class.getName()).log(Level.INFO, "Found element {0}", elem.getAttribute("path"));
|
||||||
|
elements.add(elem.getAttribute("path")); |
||||||
|
} |
||||||
|
NodeList list = elem.getChildNodes(); |
||||||
|
for (int i = 0; i < list.getLength(); i++) { |
||||||
|
if (list.item(i) instanceof Element) { |
||||||
|
Element asset = (Element) list.item(i); |
||||||
|
scanProjectFiles(asset, elements); |
||||||
|
} |
||||||
|
} |
||||||
|
return elements; |
||||||
|
} |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent ev) { |
||||||
|
final ArrayList<String> files = scanProjectFiles(context.getConfiguration().getDocumentElement(), new ArrayList<String>()); |
||||||
|
new Thread(new Runnable() { |
||||||
|
|
||||||
|
public void run() { |
||||||
|
ProgressHandle handle = ProgressHandleFactory.createHandle("Cleanup unused assets.."); |
||||||
|
handle.start(); |
||||||
|
scanFiles(context.getAssetsFolder(), files); |
||||||
|
handle.finish(); |
||||||
|
} |
||||||
|
}).start(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public Object getValue(String key) { |
||||||
|
if (key.equals(NAME)) { |
||||||
|
return "Clean unused images"; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public void putValue(String key, Object value) { |
||||||
|
} |
||||||
|
|
||||||
|
public void setEnabled(boolean b) { |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isEnabled() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public void addPropertyChangeListener(PropertyChangeListener listener) { |
||||||
|
} |
||||||
|
|
||||||
|
public void removePropertyChangeListener(PropertyChangeListener listener) { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,578 @@ |
|||||||
|
/* |
||||||
|
* To change this template, choose Tools | Templates |
||||||
|
* and open the template in the editor. |
||||||
|
*/ |
||||||
|
package com.jme3.gde.assetpack.project.actions; |
||||||
|
|
||||||
|
import com.jme3.asset.AssetEventListener; |
||||||
|
import com.jme3.asset.AssetKey; |
||||||
|
import com.jme3.asset.DesktopAssetManager; |
||||||
|
import com.jme3.gde.assetpack.AssetPackLoader; |
||||||
|
import com.jme3.gde.assetpack.XmlHelper; |
||||||
|
import com.jme3.gde.assetpack.project.AssetPackProject; |
||||||
|
import com.jme3.gde.assetpack.project.wizards.FileDescription; |
||||||
|
import com.jme3.gde.core.assets.ProjectAssetManager; |
||||||
|
import com.jme3.gde.ogretools.convert.OgreXMLConvert; |
||||||
|
import com.jme3.gde.ogretools.convert.OgreXMLConvertOptions; |
||||||
|
import com.jme3.material.MaterialList; |
||||||
|
import com.jme3.scene.plugins.ogre.OgreMeshKey; |
||||||
|
import com.jme3.scene.plugins.ogre.matext.MaterialExtension; |
||||||
|
import com.jme3.scene.plugins.ogre.matext.MaterialExtensionSet; |
||||||
|
import com.jme3.scene.plugins.ogre.matext.OgreMaterialKey; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.beans.PropertyChangeListener; |
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.OutputStream; |
||||||
|
import java.io.OutputStreamWriter; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.atomic.AtomicBoolean; |
||||||
|
import java.util.logging.Level; |
||||||
|
import java.util.logging.Logger; |
||||||
|
import javax.swing.Action; |
||||||
|
import org.netbeans.api.progress.ProgressHandle; |
||||||
|
import org.netbeans.api.progress.ProgressHandleFactory; |
||||||
|
import org.openide.DialogDisplayer; |
||||||
|
import org.openide.NotifyDescriptor; |
||||||
|
import org.openide.NotifyDescriptor.Message; |
||||||
|
import org.openide.filesystems.FileObject; |
||||||
|
import org.openide.filesystems.FileUtil; |
||||||
|
import org.openide.util.Exceptions; |
||||||
|
import org.openide.xml.XMLUtil; |
||||||
|
import org.w3c.dom.Document; |
||||||
|
import org.w3c.dom.Element; |
||||||
|
import org.xml.sax.InputSource; |
||||||
|
|
||||||
|
public final class ImportWorldForgeAction implements Action { |
||||||
|
|
||||||
|
private final AssetPackProject project; |
||||||
|
private FileObject folder; |
||||||
|
private ProjectAssetManager pm; |
||||||
|
private DesktopAssetManager mgr; |
||||||
|
private HashMap<String, ArrayList<String>> matRefs = new HashMap<String, ArrayList<String>>(); |
||||||
|
private List<String> modelNames = new ArrayList<String>(); |
||||||
|
|
||||||
|
public ImportWorldForgeAction(AssetPackProject context) { |
||||||
|
this.project = context; |
||||||
|
pm = project.getProjectAssetManager(); |
||||||
|
folder = pm.getAssetFolder(); |
||||||
|
mgr = new DesktopAssetManager(true); |
||||||
|
mgr.registerLocator(folder.getPath(), "com.jme3.asset.plugins.FileLocator"); |
||||||
|
} |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent ev) { |
||||||
|
matRefs.clear(); |
||||||
|
modelNames.clear(); |
||||||
|
// TODO use context
|
||||||
|
// javax.swing.JFileChooser fr = new javax.swing.JFileChooser();
|
||||||
|
// javax.swing.filechooser.FileSystemView fw = fr.getFileSystemView();
|
||||||
|
// String projectDir = fw.getDefaultDirectory().getAbsolutePath();
|
||||||
|
// FileChooserBuilder builder = new FileChooserBuilder(projectDir);
|
||||||
|
// builder.setApproveText("Import");
|
||||||
|
// builder.setTitle("Please select WorldForge checkout folder");
|
||||||
|
// builder.setDirectoriesOnly(true);
|
||||||
|
// final File file = builder.showOpenDialog();
|
||||||
|
// if (file == null) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//FileUtil.toFileObject(file);
|
||||||
|
new Thread(new Runnable() { |
||||||
|
|
||||||
|
public void run() { |
||||||
|
ProgressHandle handle = ProgressHandleFactory.createHandle("Import WorldForge Models"); |
||||||
|
handle.start(); |
||||||
|
FileObject objects = folder.getFileObject("3d_objects"); |
||||||
|
if (objects == null) { |
||||||
|
showError("Cannot find worldforge content!\nPlease copy content of worldforge folder\ninto the assets folder of this project!"); |
||||||
|
handle.finish(); |
||||||
|
return; |
||||||
|
} |
||||||
|
List<String> binFiles = new ArrayList<String>(); |
||||||
|
convertOgreBinary(folder.getPath(), binFiles, handle); |
||||||
|
deleteOgreBinary(binFiles); |
||||||
|
handle.progress("Scanning folder"); |
||||||
|
scanFiles(folder); |
||||||
|
//iterate through found models and add asset items
|
||||||
|
for (Iterator<String> it = modelNames.iterator(); it.hasNext();) { |
||||||
|
String modelName = it.next(); |
||||||
|
handle.progress("Scanning " + modelName); |
||||||
|
//TODO: fill data
|
||||||
|
Element elem = project.getConfiguration().createElement("asset"); |
||||||
|
elem.setAttribute("name", getFileName(modelName)); |
||||||
|
elem.setAttribute("type", "model"); |
||||||
|
elem.setAttribute("format", "ogrexml"); |
||||||
|
elem.setAttribute("categories", getCategory(modelName)); |
||||||
|
elem.setAttribute("tags", getTags(modelName)); |
||||||
|
Element description = project.getConfiguration().createElement("description"); |
||||||
|
elem.appendChild(description); |
||||||
|
|
||||||
|
|
||||||
|
List<String> matNames = getModelMaterialNames(modelName); |
||||||
|
Element variationsElement = null; |
||||||
|
MaterialList keyMaterialList = new MaterialList(); |
||||||
|
//assemble material variation assets and add variations
|
||||||
|
for (String matName : matNames) { |
||||||
|
MaterialList materialList = null; |
||||||
|
Element partElement = null; |
||||||
|
ArrayList<String> matFiles = matRefs.get(matName); |
||||||
|
if (matFiles != null) { |
||||||
|
for (String matFile : matFiles) { |
||||||
|
Element variationElement = null; |
||||||
|
if (variationsElement == null) { |
||||||
|
variationsElement = project.getConfiguration().createElement("materialvariations"); |
||||||
|
elem.appendChild(variationsElement); |
||||||
|
} |
||||||
|
if (partElement == null) { |
||||||
|
partElement = project.getConfiguration().createElement("mesh"); |
||||||
|
partElement.setAttribute("name", matName); |
||||||
|
variationsElement.appendChild(partElement); |
||||||
|
} |
||||||
|
List<AssetKey<?>> list = new ArrayList<AssetKey<?>>(); |
||||||
|
materialList = getMaterialAssetList(matFile, list); |
||||||
|
for (Iterator<AssetKey<?>> it1 = list.iterator(); it1.hasNext();) { |
||||||
|
AssetKey<? extends Object> assetKey = it1.next(); |
||||||
|
if (variationElement == null) { |
||||||
|
variationElement = project.getConfiguration().createElement("variation"); |
||||||
|
variationElement.setAttribute("name", getFolderName(matFile)); |
||||||
|
partElement.appendChild(variationElement); |
||||||
|
} |
||||||
|
FileDescription desc = AssetPackLoader.getFileDescription(getAbsoluteAssetPath(assetKey.getName())); |
||||||
|
if (desc != null) { |
||||||
|
Element file = project.getConfiguration().createElement("file"); |
||||||
|
file.setAttribute("path", assetKey.getName()); |
||||||
|
file.setAttribute("type", desc.getType()); |
||||||
|
variationElement.appendChild(file); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (materialList != null) { |
||||||
|
keyMaterialList.putAll(materialList); |
||||||
|
} |
||||||
|
} |
||||||
|
//assemble main assets and add to file
|
||||||
|
if (keyMaterialList != null) { |
||||||
|
OgreMeshKey meshKey = new OgreMeshKey(modelName, keyMaterialList); |
||||||
|
List<AssetKey<?>> list = new ArrayList<AssetKey<?>>(); |
||||||
|
if (getModelAssetList(meshKey, list)) { |
||||||
|
for (AssetKey<?> assetKey : list) { |
||||||
|
Element file = project.getConfiguration().createElement("file"); |
||||||
|
if (assetKey.getName().endsWith(".mesh.xml")) { |
||||||
|
file.setAttribute("main", "true"); |
||||||
|
} |
||||||
|
file.setAttribute("path", assetKey.getName()); |
||||||
|
FileDescription descr = AssetPackLoader.getFileDescription(getAbsoluteAssetPath(assetKey.getName())); |
||||||
|
file.setAttribute("type", descr.getType()); |
||||||
|
elem.appendChild(file); |
||||||
|
} |
||||||
|
project.getProjectAssets().appendChild(elem); |
||||||
|
project.saveSettings(); |
||||||
|
project.getAssetPackFolder().refresh(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
handle.finish(); |
||||||
|
} |
||||||
|
}).start(); |
||||||
|
} |
||||||
|
|
||||||
|
private void scanFiles(FileObject folder) { |
||||||
|
FileObject[] files = folder.getChildren(); |
||||||
|
for (FileObject fileObject : files) { |
||||||
|
if (fileObject.isFolder() && !fileObject.isVirtual()) { |
||||||
|
scanFiles(fileObject); |
||||||
|
} else if (fileObject.getPath().endsWith(".mesh.xml")) { |
||||||
|
// replaceMeshMatName(fileObject);
|
||||||
|
//TODO: workaround
|
||||||
|
if (!fileObject.getName().equals("campfire.mesh")) { |
||||||
|
modelNames.add(getRelativeAssetPath(fileObject.getPath())); |
||||||
|
} |
||||||
|
} else if ("material".equals(fileObject.getExt())) { |
||||||
|
// replaceMaterialMatName(fileObject);
|
||||||
|
String name = getMaterialName(fileObject); |
||||||
|
if (name != null) { |
||||||
|
addMaterialRef(name, getRelativeAssetPath(fileObject.getPath())); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void replaceMaterialMatName(FileObject file) { |
||||||
|
try { |
||||||
|
List<String> lines = file.asLines(); |
||||||
|
boolean changed = false; |
||||||
|
for (int i = 0; i < lines.size(); i++) { |
||||||
|
String line = lines.get(i); |
||||||
|
if (line.startsWith("material") && line.contains(":")) { |
||||||
|
int idx = line.indexOf(":"); |
||||||
|
String matName = line.substring(9, idx).trim(); |
||||||
|
String newName = removePastUnderScore(matName); |
||||||
|
if (!matName.equals(newName)) { |
||||||
|
Logger.getLogger(ImportWorldForgeAction.class.getName()).log(Level.INFO, "Change material name for {0}", file); |
||||||
|
lines.set(i, line.replace(matName, newName)); |
||||||
|
changed = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (changed) { |
||||||
|
OutputStreamWriter out = new OutputStreamWriter(file.getOutputStream()); |
||||||
|
for (String string : lines) { |
||||||
|
out.write(string + "\n"); |
||||||
|
} |
||||||
|
out.close(); |
||||||
|
} |
||||||
|
} catch (IOException ex) { |
||||||
|
Exceptions.printStackTrace(ex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void replaceMeshMatName(FileObject file) { |
||||||
|
InputStream stream = null; |
||||||
|
try { |
||||||
|
stream = file.getInputStream(); |
||||||
|
Document doc = XMLUtil.parse(new InputSource(stream), false, false, null, null); |
||||||
|
stream.close(); |
||||||
|
Element elem = doc.getDocumentElement(); |
||||||
|
if (elem == null) { |
||||||
|
throw new IllegalStateException("Cannot find root mesh element"); |
||||||
|
} |
||||||
|
Element submeshes = XmlHelper.findChildElement(elem, "submeshes"); |
||||||
|
if (submeshes == null) { |
||||||
|
throw new IllegalStateException("Cannot find submeshes element"); |
||||||
|
} |
||||||
|
Element submesh = XmlHelper.findChildElement(submeshes, "submesh"); |
||||||
|
boolean changed = false; |
||||||
|
while (submesh != null) { |
||||||
|
String matName = submesh.getAttribute("material"); |
||||||
|
String newName = removePastUnderScore(matName); |
||||||
|
if (!matName.equals(newName)) { |
||||||
|
Logger.getLogger(ImportWorldForgeAction.class.getName()).log(Level.INFO, "Change material name for {0}", file); |
||||||
|
submesh.setAttribute("material", newName); |
||||||
|
submesh = XmlHelper.findNextSiblingElement(submesh); |
||||||
|
changed = true; |
||||||
|
} |
||||||
|
} |
||||||
|
if (changed) { |
||||||
|
OutputStream out = file.getOutputStream(); |
||||||
|
XMLUtil.write(doc, out, "UTF-8"); |
||||||
|
out.close(); |
||||||
|
} |
||||||
|
|
||||||
|
} catch (Exception ex) { |
||||||
|
Exceptions.printStackTrace(ex); |
||||||
|
} finally { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String removePastUnderScore(String name) { |
||||||
|
int idx = name.lastIndexOf("/"); |
||||||
|
if (idx == -1) { |
||||||
|
return name; |
||||||
|
} |
||||||
|
int idx2 = name.indexOf("_", idx); |
||||||
|
if (idx2 == -1) { |
||||||
|
return name; |
||||||
|
} else { |
||||||
|
return name.substring(0, idx2); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void addMaterialRef(String matName, String assetName) { |
||||||
|
ArrayList<String> list = matRefs.get(matName); |
||||||
|
if (list == null) { |
||||||
|
list = new ArrayList<String>(); |
||||||
|
matRefs.put(matName, list); |
||||||
|
} |
||||||
|
list.add(assetName); |
||||||
|
} |
||||||
|
|
||||||
|
private void convertOgreBinary(String dir2scan, List<String> deleteFiles, ProgressHandle handle) { |
||||||
|
try { |
||||||
|
File zipDir = new File(dir2scan); |
||||||
|
String[] dirList = zipDir.list(); |
||||||
|
for (int i = 0; i < dirList.length; i++) { |
||||||
|
File f = new File(zipDir, dirList[i]); |
||||||
|
if (f.isDirectory()) { |
||||||
|
String filePath = f.getPath(); |
||||||
|
convertOgreBinary(filePath, deleteFiles, handle); |
||||||
|
continue; |
||||||
|
} |
||||||
|
FileObject fobj = FileUtil.toFileObject(f); |
||||||
|
if (fobj.getExt().equalsIgnoreCase("mesh") || fobj.getExt().equalsIgnoreCase("skeleton")) { |
||||||
|
OgreXMLConvertOptions options = new OgreXMLConvertOptions(fobj.getPath()); |
||||||
|
options.setBinaryFile(true); |
||||||
|
OgreXMLConvert conv = new OgreXMLConvert(); |
||||||
|
conv.doConvert(options, handle); |
||||||
|
deleteFiles.add(fobj.getPath()); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
Logger.getLogger(ConvertOgreBinaryMeshesAction.class.getName()).log(Level.SEVERE, "Error scanning directory", e); |
||||||
|
} finally { |
||||||
|
// handle.finish();
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void deleteOgreBinary(List<String> createdFiles) { |
||||||
|
for (String string : createdFiles) { |
||||||
|
new File(string).delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private OgreMaterialKey getOgreMaterialKey(String materialName) { |
||||||
|
/** |
||||||
|
* /base/normalmap/specular |
||||||
|
* /base/normalmap |
||||||
|
* /base/simple |
||||||
|
*/ |
||||||
|
MaterialExtensionSet matExts = new MaterialExtensionSet(); |
||||||
|
MaterialExtension baseLightExt = new MaterialExtension("/base/normalmap/specular", |
||||||
|
"Common/MatDefs/Light/Lighting.j3md"); |
||||||
|
baseLightExt.setTextureMapping("DiffuseMap", "DiffuseMap"); |
||||||
|
baseLightExt.setTextureMapping("NormalHeightMap", "NormalMap"); |
||||||
|
baseLightExt.setTextureMapping("SpecularMap", "SpecularMap"); |
||||||
|
matExts.addMaterialExtension(baseLightExt); |
||||||
|
|
||||||
|
MaterialExtension baseLightExt2 = new MaterialExtension("/base/normalmap", |
||||||
|
"Common/MatDefs/Light/Lighting.j3md"); |
||||||
|
baseLightExt2.setTextureMapping("DiffuseMap", "DiffuseMap"); |
||||||
|
baseLightExt2.setTextureMapping("NormalHeightMap", "NormalMap"); |
||||||
|
baseLightExt2.setTextureMapping("SpecularMap", "SpecularMap"); |
||||||
|
matExts.addMaterialExtension(baseLightExt2); |
||||||
|
|
||||||
|
MaterialExtension baseLightExt3 = new MaterialExtension("/base/simple", |
||||||
|
"Common/MatDefs/Light/Lighting.j3md"); |
||||||
|
baseLightExt3.setTextureMapping("DiffuseMap", "DiffuseMap"); |
||||||
|
baseLightExt3.setTextureMapping("NormalHeightMap", "NormalMap"); |
||||||
|
baseLightExt3.setTextureMapping("SpecularMap", "SpecularMap"); |
||||||
|
matExts.addMaterialExtension(baseLightExt3); |
||||||
|
|
||||||
|
OgreMaterialKey key = new OgreMaterialKey(materialName); |
||||||
|
key.setMaterialExtensionSet(matExts); |
||||||
|
return key; |
||||||
|
} |
||||||
|
|
||||||
|
private MaterialList getMaterialAssetList(String key, final List<AssetKey<?>> assetKeys) { |
||||||
|
final AtomicBoolean good = new AtomicBoolean(true); |
||||||
|
mgr.clearCache(); |
||||||
|
mgr.setAssetEventListener(new AssetEventListener() { |
||||||
|
|
||||||
|
public void assetLoaded(AssetKey ak) { |
||||||
|
} |
||||||
|
|
||||||
|
public void assetRequested(AssetKey ak) { |
||||||
|
if (!"j3md".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"glsllib".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"frag".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"vert".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"vert".equalsIgnoreCase(ak.getExtension())) { |
||||||
|
assetKeys.add(ak); |
||||||
|
} |
||||||
|
if (ak.getName().equals("Common/Materials/RedColor.j3m")) { |
||||||
|
good.set(false); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
try { |
||||||
|
return mgr.loadAsset(getOgreMaterialKey(key)); |
||||||
|
} catch (Exception e) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean getModelAssetList(OgreMeshKey key, final List<AssetKey<?>> assetKeys) { |
||||||
|
final AtomicBoolean good = new AtomicBoolean(true); |
||||||
|
mgr.clearCache(); |
||||||
|
mgr.setAssetEventListener(new AssetEventListener() { |
||||||
|
|
||||||
|
public void assetLoaded(AssetKey ak) { |
||||||
|
} |
||||||
|
|
||||||
|
public void assetRequested(AssetKey ak) { |
||||||
|
if (ak instanceof OgreMaterialKey) { |
||||||
|
MaterialExtensionSet matExts = new MaterialExtensionSet(); |
||||||
|
MaterialExtension baseLightExt = new MaterialExtension("/base/normalmap/specular", |
||||||
|
"Common/MatDefs/Light/Lighting.j3md"); |
||||||
|
baseLightExt.setTextureMapping("DiffuseMap", "DiffuseMap"); |
||||||
|
baseLightExt.setTextureMapping("NormalHeightMap", "NormalMap"); |
||||||
|
baseLightExt.setTextureMapping("SpecularMap", "SpecularMap"); |
||||||
|
matExts.addMaterialExtension(baseLightExt); |
||||||
|
|
||||||
|
MaterialExtension baseLightExt2 = new MaterialExtension("/base/normalmap", |
||||||
|
"Common/MatDefs/Light/Lighting.j3md"); |
||||||
|
baseLightExt2.setTextureMapping("DiffuseMap", "DiffuseMap"); |
||||||
|
baseLightExt2.setTextureMapping("NormalHeightMap", "NormalMap"); |
||||||
|
baseLightExt2.setTextureMapping("SpecularMap", "SpecularMap"); |
||||||
|
matExts.addMaterialExtension(baseLightExt2); |
||||||
|
|
||||||
|
MaterialExtension baseLightExt3 = new MaterialExtension("/base/simple", |
||||||
|
"Common/MatDefs/Light/Lighting.j3md"); |
||||||
|
baseLightExt3.setTextureMapping("DiffuseMap", "DiffuseMap"); |
||||||
|
baseLightExt3.setTextureMapping("NormalHeightMap", "NormalMap"); |
||||||
|
baseLightExt3.setTextureMapping("SpecularMap", "SpecularMap"); |
||||||
|
matExts.addMaterialExtension(baseLightExt3); |
||||||
|
|
||||||
|
((OgreMaterialKey) ak).setMaterialExtensionSet(matExts); |
||||||
|
|
||||||
|
} |
||||||
|
if (!"j3md".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"glsllib".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"frag".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"vert".equalsIgnoreCase(ak.getExtension()) |
||||||
|
&& !"vert".equalsIgnoreCase(ak.getExtension())) { |
||||||
|
assetKeys.add(ak); |
||||||
|
} |
||||||
|
if (ak.getName().equals("Common/Materials/RedColor.j3m")) { |
||||||
|
good.set(false); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
try { |
||||||
|
mgr.loadModel(key); |
||||||
|
} catch (Exception e) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (!good.get()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private List<String> getModelMaterialNames(String assetName) { |
||||||
|
List<String> materialNames = new ArrayList<String>(); |
||||||
|
//TODO: check use of File
|
||||||
|
FileObject file = FileUtil.toFileObject(new File(getAbsoluteAssetPath(assetName).replaceAll("/", File.separator)));//Repository.getDefault().findResource(getAbsoluteAssetPath(assetName));
|
||||||
|
InputStream stream = null; |
||||||
|
try { |
||||||
|
stream = file.getInputStream(); |
||||||
|
Document doc = XMLUtil.parse(new InputSource(stream), false, false, null, null); |
||||||
|
Element elem = doc.getDocumentElement(); |
||||||
|
if (elem == null) { |
||||||
|
throw new IllegalStateException("Cannot find root mesh element"); |
||||||
|
} |
||||||
|
Element submeshes = XmlHelper.findChildElement(elem, "submeshes"); |
||||||
|
if (submeshes == null) { |
||||||
|
throw new IllegalStateException("Cannot find submeshes element"); |
||||||
|
} |
||||||
|
Element submesh = XmlHelper.findChildElement(submeshes, "submesh"); |
||||||
|
while (submesh != null) { |
||||||
|
String matName = submesh.getAttribute("material"); |
||||||
|
if (!materialNames.contains(matName)) { |
||||||
|
materialNames.add(matName); |
||||||
|
} |
||||||
|
submesh = XmlHelper.findNextSiblingElement(submesh); |
||||||
|
} |
||||||
|
} catch (Exception ex) { |
||||||
|
Exceptions.printStackTrace(ex); |
||||||
|
} finally { |
||||||
|
if (stream != null) { |
||||||
|
try { |
||||||
|
stream.close(); |
||||||
|
} catch (IOException ex) { |
||||||
|
Exceptions.printStackTrace(ex); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return materialNames; |
||||||
|
} |
||||||
|
|
||||||
|
private String getMaterialName(FileObject file) { |
||||||
|
try { |
||||||
|
System.out.println("MaterialScan " + file); |
||||||
|
List<String> lines = file.asLines(); |
||||||
|
for (String line : lines) { |
||||||
|
if (line.startsWith("material") && line.contains(":")) { |
||||||
|
int idx = line.indexOf(":"); |
||||||
|
return line.substring(9, idx).trim(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} catch (IOException ex) { |
||||||
|
Exceptions.printStackTrace(ex); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private String getRelativeAssetPath(String absolutePath) { |
||||||
|
String prefix = folder.getPath(); |
||||||
|
int idx = absolutePath.indexOf(prefix); |
||||||
|
if (idx == 0) { |
||||||
|
return absolutePath.substring(prefix.length() + 1).replace("./", ""); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private String getAbsoluteAssetPath(String relatvePath) { |
||||||
|
String prefix = folder.getPath(); |
||||||
|
return (prefix + "/" + relatvePath).replace("./", ""); |
||||||
|
} |
||||||
|
|
||||||
|
private String getTags(String modelName) { |
||||||
|
String[] strings = modelName.split("/"); |
||||||
|
String ret = null; |
||||||
|
for (String string : strings) { |
||||||
|
if (!"models".equals(string) && !"3d_objects".equals(string) && !string.contains(".mesh.xml")) { |
||||||
|
if (ret == null) { |
||||||
|
ret = string; |
||||||
|
} else { |
||||||
|
ret = ret + ", " + string; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
private String getCategory(String modelName) { |
||||||
|
if (!modelName.startsWith("3d_objects/")) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
int idx = modelName.indexOf("/", 11); |
||||||
|
if (idx == -1) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
return modelName.substring(11, idx); |
||||||
|
} |
||||||
|
|
||||||
|
private String getFolderName(String name) { |
||||||
|
int start = name.substring(0, name.lastIndexOf("/")).lastIndexOf("/") + 1; |
||||||
|
return name.substring(start, name.lastIndexOf("/")); |
||||||
|
} |
||||||
|
|
||||||
|
private String getFileName(String name) { |
||||||
|
return name.substring(name.lastIndexOf("/") + 1, name.indexOf(".")); |
||||||
|
} |
||||||
|
|
||||||
|
private void showError(String e) { |
||||||
|
Message msg = new NotifyDescriptor.Message( |
||||||
|
e, |
||||||
|
NotifyDescriptor.ERROR_MESSAGE); |
||||||
|
DialogDisplayer.getDefault().notifyLater(msg); |
||||||
|
} |
||||||
|
|
||||||
|
public Object getValue(String key) { |
||||||
|
if (key.equals(NAME)) { |
||||||
|
return "Scan WorldForge.."; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
public void putValue(String key, Object value) { |
||||||
|
} |
||||||
|
|
||||||
|
public void setEnabled(boolean b) { |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isEnabled() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public void addPropertyChangeListener(PropertyChangeListener listener) { |
||||||
|
} |
||||||
|
|
||||||
|
public void removePropertyChangeListener(PropertyChangeListener listener) { |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue