This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-01-03
Channels
- # admin-announcements (91)
- # announcements (1)
- # beginners (5)
- # boot (228)
- # cljs-dev (9)
- # cljsrn (12)
- # clojars (13)
- # clojure (175)
- # clojure-art (6)
- # clojure-russia (46)
- # clojurescript (35)
- # core-matrix (62)
- # cursive (10)
- # datomic (5)
- # hoplon (119)
- # ldnclj (11)
- # leiningen (7)
- # mount (3)
- # om (21)
- # reagent (2)
- # slack-help (1)
- # spacemacs (1)
My polygon mesh generating/processing/morphing library using core.matrix is shaping up nicely: https://github.com/pkobrien/cad/tree/master/src/cad/mesh
Performance is about the same as the vector from http://thi.ng
Right now I'm not scaling my seed platonic solids properly. Basic stuff. I'm reading up on 3D graphics algorithms so I actually know what I'm doing at a lower level.
And I ran into an old issue with -0.0 in my normals but haven't been able to recreate it yet this morning.
Anyhow, I should have these issues resolved today. Then I will start looking at performance more.
Right now one of my main bottlenecks is in writing to the X3D xml files. I'm going to have to create a custom writer to make it lazier because I've maxed out all the tricks I can play with making things lazy using clojure.data.xml
Okay, scaling has been properly implemented and the platonic solid construction looks pretty good now.
This is how I'm calculating a face normal now:
(defn normal
"Returns the ortho normal of the first three points passed in."
([[a b c]]
(normal a b c))
([a b c]
(mx/normalise! (mx/cross (mx/sub b a) (mx/sub c a)))))
The problem is that this can create a Vector3 having an x, y, or z component with a value of -0.0 and Clojure has a bug related to that which messes up some other functions of mine.
So my fix in my old code was to do this:
(defn normal
"Returns the ortho normal of the first three points passed in."
([[a b c]] (normal a b c))
;([a b] (gc/normalize (gc/cross a b)))
([a b c] (apply point (mapv (comp mu/round2safe mu/abs-zero)
(mx/normalise (mx/cross (- b a) (- c a)))))))
@mikera: Now that I'm using core.matrix what's the best way to apply abs-zero
to a Vector3
as part of my normal
function?
(def ZERO-VECTOR3 (Vector3/of 0.0 0.0 0.0)) (defn abs-zero [^Vector3 v] (if (.isZero v) ZERO-VECTOR3 v))
i.e. replace with a constant zero Vector3 whenever required. Avoids unnecessary new allocations.
That costs you one extra protocol dispatch.... so not too much but might be painful in an inner loop
@mikera: We're not quite on the same page. I only need to replace one component of the Vector3 if it is -0.0. The other components might be okay. So, for example [1.0 -0.0 5.25]
It is about 5x faster than a Clojure mapv on my machine, even with small vectors like this
About to do a new release of vectorz-clj.... any issues discovered that you'd like a fix for?
No, all the problems I'm having are my own doing. Haven't found any problems with core.matrix so far.
that fix works like a charm: (mx/emap mu/abs-zero (mx/normalise! (mx/cross (mx/sub b a) (mx/sub c a))))
oh, I can make that (mx/emap! mu/abs-zero (mx/normalise! (mx/cross (mx/sub b a) (mx/sub c a))))
can't I?
@mikera: I'm getting this error: CompilerException java.lang.ClassCastException: mikera.vectorz.Vector3 cannot be cast to java.lang.Number,
when I try to do this:
opposite-face (fn [outer-face thickness]
(vec (for [vert (reverse outer-face)]
(+ vert
(* (vert-normal-map vert) (- thickness))))))
ah, this is failing:
(defn normal
"Returns the normal for the vertex as the average of the face normals."
[mesh vert]
(let [face-normal-map (mp/face-normal-map mesh)
vert-faces-map (mp/vert-faces-map mesh)
xf (comp (map face-normal-map) (distinct))
vnorm (fn [vert]
(->> (vert-faces-map vert)
(transduce xf + (mc/point 0 0 0))
(mx/normalise!)))]
(vnorm vert)))
Are your + and * the core.matrix operators or the clojure ones? That's the error I'd expect if you try and pass a vector to a clojure numerical operator
Also worth checking the types of values are correct at each stage of your operations. I recommend unit tests to do that, especially for the results of functions like face-normal-map
I have no unit tests yet - this has been a WIP - I've only been doing the mesh processing for a couple of weeks and only a week ago decided to create my own library, so I've only just fleshed this out. Once I'm happy with the overall shape, and I think it has shaped up nicely, I will move all this mesh stuff over to my decomplect.ion
namespace/github repository and will add unit tests.