Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Vector from './vector';
- import Intersection from './intersection';
- import Ray from './ray';
- import Material from './material';
- import Shader from './shader';
- /**
- * A class representing a sphere
- */
- export default class Sphere {
- vertexBuffer: WebGLBuffer;
- /**
- * The indices describing which vertices form a triangle
- */
- indexBuffer: WebGLBuffer;
- /**
- * The normals on the surface at each vertex location
- */
- normalBuffer: WebGLBuffer;
- /**
- * The color of each vertex
- */
- ambientBuffer: WebGLBuffer;
- diffuseBuffer: WebGLBuffer;
- specularBuffer: WebGLBuffer;
- /**
- * The amount of indices
- *
- */
- // colorBuffer: WebGLBuffer;
- elements: number;
- /**
- * Creates a new Sphere with center and radius
- * @param center The center of the Sphere
- * @param radius The radius of the Sphere
- * @param color The color of the Sphere
- */
- constructor(
- private gl: WebGL2RenderingContext,
- public center: Vector = new Vector(0, 0, 0, 1),
- public radius: number = .5,
- public material: Material = Material.simply["red"]
- ) {
- let vertices = [];
- let indices = [];
- let normals = [];
- if(!gl){
- return;
- }
- let ringsize = 30;
- for (let ring = 0; ring < ringsize; ring++) {
- for (let ring2 = 0; ring2 < ringsize; ring2++) {
- let theta = ring * Math.PI * 2 / ringsize ;
- let phi = ring2 * Math.PI * 2 / ringsize;
- let x = (radius *
- Math.sin(theta) *
- Math.cos(phi) +
- center.x
- );
- let y = (radius *
- Math.sin(theta) *
- Math.sin(phi) +
- center.y
- );
- let z = (radius *
- Math.cos(theta) +
- center.z-2
- );
- vertices.push(x);
- vertices.push(y);
- vertices.push(z);
- let normal = (new Vector(x, y, z, 1)).sub(center).normalize();
- normals.push(normal.x);
- normals.push(normal.y);
- normals.push(normal.z);
- }
- }
- for (let ring = 0; ring < ringsize / 2; ring++) {
- for (let ring2 = 0; ring2 < ringsize; ring2++) {
- indices.push(ring * ringsize + ring2);
- indices.push((ring + 1) * ringsize + ring2);
- indices.push(ring * ringsize + ((ring2 + 1) % ringsize));
- indices.push(ring * ringsize + ((ring2 + 1) % ringsize));
- indices.push((ring + 1) * ringsize + ring2);
- indices.push((ring + 1) * ringsize + ((ring2 + 1) % ringsize));
- }
- }
- const vertexBuffer = this.gl.createBuffer();
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
- this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(vertices), this.gl.STATIC_DRAW);
- this.vertexBuffer = vertexBuffer;
- const indexBuffer = gl.createBuffer();
- this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
- this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), this.gl.STATIC_DRAW);
- this.indexBuffer = indexBuffer;
- const normalBuffer = this.gl.createBuffer();
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, normalBuffer);
- this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(normals), this.gl.STATIC_DRAW);
- this.normalBuffer = normalBuffer;
- this.elements = indices.length;
- // TODO create colorBuffer
- var color = [1,0,1, 1,0,1, 1,0,1, ];
- const ambientBuffer = this.gl.createBuffer();
- const diffuseBuffer = this.gl.createBuffer();
- const specularBuffer= this.gl.createBuffer();
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, ambientBuffer);
- this.gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(color), this.gl.STATIC_DRAW);
- this.ambientBuffer = ambientBuffer;
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, diffuseBuffer);
- this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(color), this.gl.STATIC_DRAW);
- this.diffuseBuffer = diffuseBuffer;
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, specularBuffer);
- this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(color), this.gl.STATIC_DRAW);
- this.specularBuffer = specularBuffer;
- console.log("INITIALIZER completed");
- }
- /**
- * Calculates the intersection of the sphere with the given ray
- * @param ray The ray to intersect with
- * @return The intersection if there is one, null if there is none
- */
- intersect(ray: Ray): Intersection | null {
- const rayDirection = ray.direction.normalize();
- const rayOrigin = ray.origin.sub(this.center);
- const a = (rayOrigin.dot(rayDirection)) ** 2;
- const b = (rayOrigin.dot(rayOrigin));
- const c = (this.radius ** 2);
- const discriminant = a - b + c;
- if (discriminant < 0){
- return null;
- } else {
- const t1 = (-rayOrigin.dot(rayDirection)) + (Math.sqrt(discriminant));
- const t2 = (-rayOrigin.dot(rayDirection)) - (Math.sqrt(discriminant));
- const t = Math.min(t1, t2);
- const interactionPoint = rayDirection.mul(t).add(ray.origin);
- const surfaceNormal = (interactionPoint.sub(this.center)).normalize();
- return new Intersection(t, interactionPoint, surfaceNormal, this.material);
- }
- }
- /**
- * Renders the sphere
- * @param {Shader} shader - The shader used to render
- */
- render(shader: Shader) { // overload target
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
- const positionLocation = shader.getAttributeLocation("a_position");
- this.gl.enableVertexAttribArray(positionLocation);
- this.gl.vertexAttribPointer(positionLocation, 3, this.gl.FLOAT, false, 0, 0);
- // TODO: bind color buffer
- const colorLocation = shader.getAttributeLocation( "a_vertexColor");
- this.gl.vertexAttribPointer(colorLocation, //buffer
- 3, // count
- this.gl.FLOAT, //type
- false, // normalize
- 4, // wie viel überspringen pro schritt (stride)
- 0 // wie viele am anfang vernachlässigen (offset)
- );
- this.gl.enableVertexAttribArray(colorLocation);
- console.log("colorLocation is : "); console.log(colorLocation);
- //shader.getUniformVec3("v_color").set(new Vector(0.2,0.4,0.0));
- this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
- this.gl.drawElements(this.gl.TRIANGLES, this.elements, this.gl.UNSIGNED_SHORT, 0);
- // this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
- // this.gl.drawElements(this.gl.TRIANGLES, this.elements, this.gl.UNSIGNED_SHORT, 0);
- //
- // this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
- // this.gl.drawElements(this.gl.TRIANGLES, this.elements, this.gl.UNSIGNED_SHORT, 0);
- //this.gl.disableVertexAttribArray(positionLocation);
- //this.gl.disableVertexAttribArray(colorLocation);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment