📄 particlesurface.java
字号:
package org.sunflow.core.primitive;import org.sunflow.SunflowAPI;import org.sunflow.core.IntersectionState;import org.sunflow.core.ParameterList;import org.sunflow.core.PrimitiveList;import org.sunflow.core.Ray;import org.sunflow.core.ShadingState;import org.sunflow.core.ParameterList.FloatParameter;import org.sunflow.math.BoundingBox;import org.sunflow.math.Matrix4;import org.sunflow.math.OrthoNormalBasis;import org.sunflow.math.Point3;import org.sunflow.math.Solvers;import org.sunflow.math.Vector3;public class ParticleSurface implements PrimitiveList { private float[] particles; private float r, r2; private int n; public ParticleSurface() { particles = null; r = r2 = 1; n = 0; } public int getNumPrimitives() { return n; } public float getPrimitiveBound(int primID, int i) { float c = particles[primID * 3 + (i >>> 1)]; return (i & 1) == 0 ? c - r : c + r; } public BoundingBox getWorldBounds(Matrix4 o2w) { BoundingBox bounds = new BoundingBox(); for (int i = 0, i3 = 0; i < n; i++, i3 += 3) bounds.include(particles[i3], particles[i3 + 1], particles[i3 + 2]); bounds.include(bounds.getMinimum().x - r, bounds.getMinimum().y - r, bounds.getMinimum().z - r); bounds.include(bounds.getMaximum().x + r, bounds.getMaximum().y + r, bounds.getMaximum().z + r); return o2w == null ? bounds : o2w.transform(bounds); } public void intersectPrimitive(Ray r, int primID, IntersectionState state) { int i3 = primID * 3; float ocx = r.ox - particles[i3 + 0]; float ocy = r.oy - particles[i3 + 1]; float ocz = r.oz - particles[i3 + 2]; float qa = r.dx * r.dx + r.dy * r.dy + r.dz * r.dz; float qb = 2 * ((r.dx * ocx) + (r.dy * ocy) + (r.dz * ocz)); float qc = ((ocx * ocx) + (ocy * ocy) + (ocz * ocz)) - r2; double[] t = Solvers.solveQuadric(qa, qb, qc); if (t != null) { // early rejection if (t[0] >= r.getMax() || t[1] <= r.getMin()) return; if (t[0] > r.getMin()) r.setMax((float) t[0]); else r.setMax((float) t[1]); state.setIntersection(primID, 0, 0); } } public void prepareShadingState(ShadingState state) { state.init(); state.getRay().getPoint(state.getPoint()); Point3 localPoint = state.getInstance().transformWorldToObject(state.getPoint()); localPoint.x -= particles[3 * state.getPrimitiveID() + 0]; localPoint.y -= particles[3 * state.getPrimitiveID() + 1]; localPoint.z -= particles[3 * state.getPrimitiveID() + 2]; state.getNormal().set(localPoint.x, localPoint.y, localPoint.z); state.getNormal().normalize(); state.setShader(state.getInstance().getShader(0)); state.setModifier(state.getInstance().getModifier(0)); // into object space Vector3 worldNormal = state.getInstance().transformNormalObjectToWorld(state.getNormal()); state.getNormal().set(worldNormal); state.getNormal().normalize(); state.getGeoNormal().set(state.getNormal()); state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal())); } public boolean update(ParameterList pl, SunflowAPI api) { FloatParameter p = pl.getPointArray("particles"); if (p != null) particles = p.data; r = pl.getFloat("radius", r); r2 = r * r; n = pl.getInt("num", n); return particles != null && n <= (particles.length / 3); } public PrimitiveList getBakingPrimitives() { return null; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -