📄 sphere.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 Sphere implements PrimitiveList {
public boolean update(ParameterList pl, SunflowAPI api) {
return true;
}
public BoundingBox getWorldBounds(Matrix4 o2w) {
BoundingBox bounds = new BoundingBox(1);
if (o2w != null)
bounds = o2w.transform(bounds);
return bounds;
}
public float getPrimitiveBound(int primID, int i) {
return (i & 1) == 0 ? -1 : 1;
}
public int getNumPrimitives() {
return 1;
}
public void prepareShadingState(ShadingState state) {
state.init();
state.getRay().getPoint(state.getPoint());
Instance parent = state.getInstance();
Point3 localPoint = parent.transformWorldToObject(state.getPoint());
state.getNormal().set(localPoint.x, localPoint.y, localPoint.z);
state.getNormal().normalize();
float phi = (float) Math.atan2(state.getNormal().y, state.getNormal().x);
if (phi < 0)
phi += 2 * Math.PI;
float theta = (float) Math.acos(state.getNormal().z);
state.getUV().y = theta / (float) Math.PI;
state.getUV().x = phi / (float) (2 * Math.PI);
Vector3 v = new Vector3();
v.x = -2 * (float) Math.PI * state.getNormal().y;
v.y = 2 * (float) Math.PI * state.getNormal().x;
v.z = 0;
state.setShader(parent.getShader(0));
state.setModifier(parent.getModifier(0));
// into world space
Vector3 worldNormal = parent.transformNormalObjectToWorld(state.getNormal());
v = parent.transformVectorObjectToWorld(v);
state.getNormal().set(worldNormal);
state.getNormal().normalize();
state.getGeoNormal().set(state.getNormal());
// compute basis in world space
state.setBasis(OrthoNormalBasis.makeFromWV(state.getNormal(), v));
}
public void intersectPrimitive(Ray r, int primID, IntersectionState state) {
// intersect in local space
float qa = r.dx * r.dx + r.dy * r.dy + r.dz * r.dz;
float qb = 2 * ((r.dx * r.ox) + (r.dy * r.oy) + (r.dz * r.oz));
float qc = ((r.ox * r.ox) + (r.oy * r.oy) + (r.oz * r.oz)) - 1;
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(0, 0, 0);
}
}
public PrimitiveList getBakingPrimitives() {
return null;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -