📄 banchoffsurface.java
字号:
package org.sunflow.core.primitive;
import org.sunflow.SunflowAPI;
import org.sunflow.core.Instance;
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.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 BanchoffSurface implements PrimitiveList {
public boolean update(ParameterList pl, SunflowAPI api) {
return true;
}
public BoundingBox getWorldBounds(Matrix4 o2w) {
BoundingBox bounds = new BoundingBox(1.5f);
if (o2w != null)
bounds = o2w.transform(bounds);
return bounds;
}
public float getPrimitiveBound(int primID, int i) {
return (i & 1) == 0 ? -1.5f : 1.5f;
}
public int getNumPrimitives() {
return 1;
}
public void prepareShadingState(ShadingState state) {
state.init();
state.getRay().getPoint(state.getPoint());
Instance parent = state.getInstance();
Point3 n = parent.transformWorldToObject(state.getPoint());
state.getNormal().set(n.x * (2 * n.x * n.x - 1), n.y * (2 * n.y * n.y - 1), n.z * (2 * n.z * n.z - 1));
state.getNormal().normalize();
state.setShader(parent.getShader(0));
state.setModifier(parent.getModifier(0));
// into world space
Vector3 worldNormal = parent.transformNormalObjectToWorld(state.getNormal());
state.getNormal().set(worldNormal);
state.getNormal().normalize();
state.getGeoNormal().set(state.getNormal());
// create basis in world space
state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
}
public void intersectPrimitive(Ray r, int primID, IntersectionState state) {
// intersect in local space
float rd2x = r.dx * r.dx;
float rd2y = r.dy * r.dy;
float rd2z = r.dz * r.dz;
float ro2x = r.ox * r.ox;
float ro2y = r.oy * r.oy;
float ro2z = r.oz * r.oz;
// setup the quartic coefficients
// some common terms could probably be shared across these
double A = (rd2y * rd2y + rd2z * rd2z + rd2x * rd2x);
double B = 4 * (r.oy * rd2y * r.dy + r.oz * r.dz * rd2z + r.ox * r.dx * rd2x);
double C = (-rd2x - rd2y - rd2z + 6 * (ro2y * rd2y + ro2z * rd2z + ro2x * rd2x));
double D = 2 * (2 * ro2z * r.oz * r.dz - r.oz * r.dz + 2 * ro2x * r.ox * r.dx + 2 * ro2y * r.oy * r.dy - r.ox * r.dx - r.oy * r.dy);
double E = 3.0f / 8.0f + (-ro2z + ro2z * ro2z - ro2y + ro2y * ro2y - ro2x + ro2x * ro2x);
// solve equation
double[] t = Solvers.solveQuartic(A, B, C, D, E);
if (t != null) {
// early rejection
if (t[0] >= r.getMax() || t[t.length - 1] <= r.getMin())
return;
// find first intersection in front of the ray
for (int i = 0; i < t.length; i++) {
if (t[i] > r.getMin()) {
r.setMax((float) t[i]);
state.setIntersection(0, 0, 0);
return;
}
}
}
}
public PrimitiveList getBakingPrimitives() {
return null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -