Initial commit

This commit is contained in:
Jeremy Penner 2013-11-21 09:09:02 -05:00
commit 1c7a26136b
5 changed files with 207 additions and 0 deletions

12
.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
/target
/lib
/classes
/checkouts
pom.xml
pom.xml.asc
*.jar
*.class
.lein-deps-sum
.lein-failures
.lein-plugins
.lein-repl-history

35
README.md Normal file
View file

@ -0,0 +1,35 @@
# cko2dae
FIXME: description
## Installation
Download from http://example.com/FIXME.
## Usage
FIXME: explanation
$ java -jar cko2dae-0.1.0-standalone.jar [args]
## Options
FIXME: listing of options this app accepts.
## Examples
...
### Bugs
...
### Any Other Sections
### That You Think
### Might be Useful
## License
Copyright © 2013 FIXME
Distributed under the Eclipse Public License, the same as Clojure.

3
doc/intro.md Normal file
View file

@ -0,0 +1,3 @@
# Introduction to cko2dae
TODO: write [great documentation](http://jacobian.org/writing/great-documentation/what-to-write/)

8
project.clj Normal file
View file

@ -0,0 +1,8 @@
(defproject cko2dae "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/data.xml "0.0.7"]]
:main cko2dae.core)

149
src/cko2dae/core.clj Normal file
View file

@ -0,0 +1,149 @@
(ns cko2dae.core
(:require clojure.string
[clojure.data.xml :as xml]
fs.core)
(:import java.text.SimpleDateFormat
java.util.Calendar
java.util.TimeZone)
(:gen-class))
(defrecord vec3 [x y z])
(defrecord mat [colour])
(defrecord poly [rgvec3 mat])
(defrecord cube [vec3 mat])
(defn rgpoly-quad [v1 v2 v3 v4 mat]
[(->poly [v1 v2 v3] mat) (->poly [v3 v2 v4] mat)])
(defn rgpoly-cube [vec3 mat]
(let [{:keys [x y z]} vec3
x_ (+ 1 x), y_ (+ 1 y), z_ (+ 1 z)
qFront (rgpoly-quad (->vec3 x y z) (->vec3 x y_ z) (->vec3 x_ y z) (->vec3 x_ y_ z) mat)
qBack (rgpoly-quad (->vec3 x y z_) (->vec3 x_ y z_) (->vec3 x y_ z_) (->vec3 x_ y_ z_) mat)
qTop (rgpoly-quad (->vec3 x y_ z) (->vec3 x y_ z_) (->vec3 x_ y_ z) (->vec3 x_ y_ z_) mat)
qBot (rgpoly-quad (->vec3 x y z) (->vec3 x_ y z) (->vec3 x y z_) (->vec3 x_ y z_) mat)
qLeft (rgpoly-quad (->vec3 x y z) (->vec3 x y z_) (->vec3 x y_ z) (->vec3 x y_ z_) mat)
qRight (rgpoly-quad (->vec3 x_ y z) (->vec3 x_ y_ z) (->vec3 x_ y z_) (->vec3 x_ y_ z_) mat)]
(concat qTop qBot qFront qBack qLeft qRight)))
(defn dedup [rgval]
(loop [i 0
rgval rgval
mpval_i {}
rgval_result []]
(if (seq rgval)
(let [val (first rgval)]
(if (nil? (get mpval_i val))
(recur (inc i) (next rgval) (assoc mpval_i val i) (conj rgval_result val))
(recur i (next rgval) mpval_i rgval_result)))
[mpval_i rgval_result])))
(defn dae-vec3-array [rgvec3 id x y z]
(let [rgfloat (apply concat (map (fn [{:keys [x y z]}] [x y z]) rgvec3))]
[:source {:id id}
[:float_array {:id (str id "_array") :count (count rgfloat)}
(clojure.string/join " " rgfloat)]
[:technique_common {}
[:accessor {:source (str "#" id "_array") :count (count rgvec3) :stride 3}
[:param {:name x :type "float"}]
[:param {:name y :type "float"}]
[:param {:name z :type "float"}]]]]))
(defn dae-geom-from-rgpoly [rgpoly id name]
(let [rgtri (apply concat (map :rgvec3 rgpoly))
[mpvec3_i rgvec3] (dedup rgtri)
points_id (str id "_points")
vertices_id (str id "_vertices")]
[:geometry {:id id :name name}
[:mesh {}
(dae-vec3-array rgvec3 points_id "X" "Y" "Z")
;todo: normals, textures
[:vertices {:id vertices_id}
[:input {:semantic "POSITION" :source (str "#" points_id)}]]
[:triangles {:count (count rgpoly)}
[:input {:semantic "VERTEX" :source (str "#" vertices_id) :offset 0}]
[:p {} (clojure.string/join " " (map #(get mpvec3_i %) rgtri))]]]]))
(defn now
"Returns current ISO 8601 compliant date."
[]
(let [f (SimpleDateFormat. "yyyy-MM-dd'T'HH:mm:ss'Z'")]
(.setTimeZone f (TimeZone/getTimeZone "GMT"))
(.format f (.getTime (Calendar/getInstance)))))
(defn dae-from-desc [libs scene]
(-> [:COLLADA {:xmlns "http://www.collada.org/2005/11/COLLADASchema" :version "1.4.1"}
[:asset
[:created {} (now)]
[:modified {} (now)]
[:up_axis {} "Y_UP"]]]
(into
(for [[lib nodes] libs]
(into [(keyword (str "library_" (name lib))) {}] nodes)))
(conj [:scene {} scene])))
(defn dae-from-rgpoly [rgpoly name]
(dae-from-desc {:geometries [(dae-geom-from-rgpoly rgpoly (str "id_" name) name)]
:visual_scenes [[:visual_scene {:id (str "id_" name "_scene") :name (str name "_scene")}
[:node {:id (str name "_node") :name name :type "NODE"}
[:instance_geometry {:url (str "#id_" name)}]]]]}
[:instance_visual_scene {:url (str "#id_" name "_scene")}]))
(defn parse-number
"Reads a number from a string. Returns nil if not a number."
[s]
(if (re-find #"^-?\d+\.?\d*$" s)
(read-string s)))
(defn rgcube-from-cko [cko]
(let [[header version count & rgstcube] (clojure.string/split-lines cko)]
; todo check header, version, count
(for [stcube rgstcube]
(let [[x y z mat] (clojure.string/split stcube (re-pattern " +"))]
(->cube (->vec3 (parse-number x) (parse-number y) (parse-number z)) (->mat mat))))))
(defn rgpoly-from-rgcube [rgcube]
(apply concat (for [{:keys [vec3 mat]} rgcube] (rgpoly-cube vec3 mat))))
(defn name-from-filename [filename]
(first (fs.core/split-ext filename)))
(defn filename-with-ext [filename ext]
(let [extPrev (second (fs.core/split-ext filename))
filenameStripped (subs filename 0 (- (count filename) (count extPrev)))]
(str filenameStripped ext)))
(defn convert-cko-to-dae [filenameIn]
(let [filenameOut (filename-with-ext filenameIn ".dae")
name (name-from-filename filenameIn)]
(-> (slurp filenameIn)
rgcube-from-cko
rgpoly-from-rgcube
(write-dae name filenameOut))))
(defn write-dae [rgpoly name filename]
(let [xml (-> rgpoly
(dae-from-rgpoly name)
xml/sexp-as-element
xml/emit-str)]
(spit filename xml)))
(defn write-test-cube []
(write-dae (rgpoly-cube (->vec3 0 0 0) nil) "cube" "C:/dev/unity/cube.dae"))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(let [xml (->
;(slurp "C:/dev/unity/w.cko")
;rgcube-from-cko
;rgpoly-from-rgcube
(rgpoly-cube (->vec3 0 0 0) nil)
(dae-from-rgpoly "cube")
xml/sexp-as-element
xml/emit-str)]
(spit "C:/dev/unity/cube.dae" xml)))
;(convert-cko-to-dae "C:/dev/unity/genie-hand.cko")
;(write-test-cube)