OpenCOLLADAで書き出すCOLLADAファイルにはオブジェクトごとに設定したユーザー定義プロパティを含める事ができます。
ユーザー定義プロパティっていうのは、モデリングソフト等で↓こんな感じにオブジェクトごとに自由に設定できるデータで、自分はA3D+Jiglibでコリジョン設定をする際に剛体のパラメータに使おうかなって思ってました。

※書き出し時に赤枠の所にチェックを入れるとユーザー定義データが含められる

ただ、Alternativa3D7.7がユーザー定義データをパースしてくれているかがちょっとわからなくて。Object3Dにそれっぽいパラメータが見当たらなかったから多分パースしてないのかな?
よくわからないので、ユーザー定義プロパティだけをパースするクラスを作ってみました。
ユーザー定義プロパティっていうのは、モデリングソフト等で↓こんな感じにオブジェクトごとに自由に設定できるデータで、自分はA3D+Jiglibでコリジョン設定をする際に剛体のパラメータに使おうかなって思ってました。

※書き出し時に赤枠の所にチェックを入れるとユーザー定義データが含められる

ただ、Alternativa3D7.7がユーザー定義データをパースしてくれているかがちょっとわからなくて。Object3Dにそれっぽいパラメータが見当たらなかったから多分パースしてないのかな?
よくわからないので、ユーザー定義プロパティだけをパースするクラスを作ってみました。
色々と自信のないソース
package {
import alternativa.engine3d.core.Object3D;
import flash.utils.Dictionary;
/**
* OpenCOLLADAで書き出したデータからユーザー定義プロパティをパースする
*/
public class UserDataParser {
private var _data:Dictionary = new Dictionary();
public function UserDataParser() {
}
/**
* ユーザー定義プロパティをパース
* @param xml COLLADAデータ
* @param objects ParserColladaでパースしたObject3Dの配列
*/
public function parse(xml:XML, objects:Vector.<Object3D>):void {
var ns:Namespace = xml.namespace();
var users:Array = [];
for each(var item:XML in xml..ns::library_visual_scenes.ns::visual_scene.ns::node) {
var user:Object = { };
users.push(user);
var userProp:String = item..ns::technique.(@profile == "OpenCOLLADA").ns::user_properties;
if (!userProp) continue;
var params:Array = userProp.replace(/\r\n|\n/g, "\r").split("\r");
for each(var p:String in params) {
var match:Array = p.match(/^(.*)=(.*)$/);
if (!match) continue;
var atr:String = trim(match[1]);
if (!atr) continue;
user[atr] = scanValue(match[2]);
}
}
for (var i:int = 0; i < objects.length; i++) {
_data[objects[i]] = users[i];
}
}
/**
* 文字列をNumber,String,Array,Booleanに変換する
* @param str
* @return
*/
public function scanValue(str:String):* {
str = trim(str);
if (!str) return null;
var s0:String = str.substr(0, 1);
var s1:String = str.substr(-1, 1);
var value:*;
if ((s0 == '"' && s1 == '"') || (s0 == "'" && s1 == "'")) {
value = str.substr(1, str.length-2);
} else if (str == "true" || str == "false") {
value = str == "true";
} else if (s0 == '[' && s1 == ']') {
value = scanArray(str.substr(1, str.length - 2));
} else {
value = Number(str);
}
return value;
}
private function scanArray(str:String):Array {
var values:Array = [];
str = trim(str);
if (!str) return values;
var buffer:String = "";
var qt:String = "";
var cnt:int = 0;
var isString:Boolean = false;
var strings:Array = str.split("");
for each(var s:String in strings) {
if (!isString && s == "," && !cnt) {
values.push(scanValue(buffer));
buffer = "";
} else {
if (!isString && (s == '"' || s == "'")) {
isString = true;
qt = s;
} else if (isString && s == qt) {
isString = false;
}
if (!isString) {
if (s == "[") cnt++;
if (s == "]") cnt--;
}
buffer += s;
}
}
values.push(scanValue(buffer));
return values;
}
private function trim(str:String):String {
return str.replace(/^\s+|\s+$/g, "");
}
/**
* ユーザー定義プロパティを取得
* @param obj
* @return
*/
public function getData(obj:Object3D):Object {
return _data[obj];
}
}
}
このパーサはXMLからユーザー定義プロパティだけをパースするだけなので、COLLADAモデルは別にParserColladaでパースしておく必要があります。
(2011/4/30追記)親子関係のリンクがあった時の処理を組んでいなかったので、子以下のオブジェクトのプロパティが取れないかもしれません。
使い方
//COLLADAデータ
var xml:XML = <COLLADA>~</COLLADA>;
//COLLADAをパース
var parser:ParserCollada = new ParserCollada();
parser.parse(xml);
//XMLとParserCollada.objectsを渡してユーザー定義プロパティをパース
var user:UserDataParser = new UserDataParser();
user.parse(xml, parser.objects);
//名前がmojaのオブジェクトを取得
var moja:Object3D = parser.getObjectByName("moja");
//mojaのユーザー定義データを取得
var data:Object = user.getData(moja);
//mojaにtype="hoge"ってユーザー定義データがある場合、hogeがトレースされる
trace(data.type);
モデリングソフトで設定するユーザー定義プロパティの書式
(例)hoge = "moja"
foo=123.4
test = [3, "@", -0.5, ["xxx","yyy"], false]
flag=true
- 変数=値(セミコロンはつけない)
- イコール前後や配列内のスペースはあってもなくてもいい
- 値が数値、文字列、配列、ブーリアンならパースできる
- 配列は入れ子になっていても大丈夫
- 「"」か「'」で囲うと文字列になる










コメントする