Beispiel #1
0
func parseMaterial(world *scene.Scene, jsondata map[string]interface{}, material_id string) (material *objects.Material) {
	log.Println("Parsing Json Material")
	materialdata := jsondata["materials"].(map[string]interface{})[material_id].(map[string]interface{})
	material = new(objects.Material)

	material.ID = material_id
	material.Type = materialdata["type"].(string)

	if materialdata["parameters"].(map[string]interface{})["materials"] == nil {
		material.Color = util.Uint32toVec3ui8(uint32(materialdata["parameters"].(map[string]interface{})["color"].(float64)))
		material.Ambient = util.Uint32toVec3ui8(uint32(materialdata["parameters"].(map[string]interface{})["ambient"].(float64)))
		material.Emissive = util.Uint32toVec3ui8(uint32(materialdata["parameters"].(map[string]interface{})["emissive"].(float64)))
		material.Transparent = materialdata["parameters"].(map[string]interface{})["transparent"].(bool)
		material.Reflectivity = float32(materialdata["parameters"].(map[string]interface{})["reflectivity"].(float64))
		material.Opacity = float32(materialdata["parameters"].(map[string]interface{})["opacity"].(float64))
		material.Wireframe = materialdata["parameters"].(map[string]interface{})["wireframe"].(bool)
		material.WireframeLinewidth = int32(materialdata["parameters"].(map[string]interface{})["wireframeLinewidth"].(float64))
	} else {
		materials := materialdata["parameters"].(map[string]interface{})["materials"].([]interface{})
		for _, v := range materials {
			id := v.(string)
			if world.HasMaterial(id) {
				material.Materials = append(material.Materials, world.GetMaterial(id))
			} else {
				material.Materials = append(material.Materials, parseMaterial(world, jsondata, id))
			}
		}
	}

	return
}
Beispiel #2
0
func Render(world *scene.Scene, w, h uint32, canvas *image.RGBA) {
	for {

		log.Println("Starting tracing rays")
		world.Lock()
		//generate principal ray(s)
		principalRays := getPrincipalRays(world, w, h)
		//intersect ray(s)
		intersect(world, principalRays, canvas)
		//get color
		world.Unlock()
		log.Println("Done tracing rays")
		break
	}
	return
}
Beispiel #3
0
func parseObjects(world *scene.Scene, jsondata map[string]interface{}) {
	items := jsondata["objects"].(map[string]interface{})
	log.Println("Parsing Json Objects")
	for k, v := range items {
		if strings.Contains(k, "camera") {
			val := v.(map[string]interface{})
			world.Camera.Type = val["type"].(string)
			world.Camera.FOV = float32(val["fov"].(float64) * (2 * math.Pi / 360))
			world.Camera.Near = float32(val["near"].(float64))
			world.Camera.Far = float32(val["far"].(float64))
			// world.Camera.Position.X = float32(val["position"].([]interface{})[0].(float64))
			// world.Camera.Position.Y = float32(val["position"].([]interface{})[1].(float64))
			// world.Camera.Position.Z = float32(val["position"].([]interface{})[2].(float64))
			// Let's override the camera position and put it in a sensible position
			world.Camera.Position.X = 0
			world.Camera.Position.Y = 0
			world.Camera.Position.Z = float32((-1) * (800 / math.Tan((float64(world.Camera.FOV) / 2))))
			world.Camera.Position.W = 1
			world.Camera.Rotation = quaternion.Quaternion{X: 0, Y: 0, Z: 0, W: 1}
			delete(items, k)
		} else if strings.Contains(k, "light") {
			var light objects.Light
			val := v.(map[string]interface{})
			light.Type = val["type"].(string)
			light.Colour = util.Uint32toVec3ui8(uint32(val["color"].(float64)))
			light.Intensity = float32(val["intensity"].(float64))
			light.Direction.X = float32(val["direction"].([]interface{})[0].(float64))
			light.Direction.Y = float32(val["direction"].([]interface{})[1].(float64))
			light.Direction.Z = float32(val["direction"].([]interface{})[2].(float64))
			light.Target = val["target"].(string)
			world.Lights = append(world.Lights, light)
			delete(items, k)
		}
	}
	world.Objects = append(world.Objects, parsePhysicalObjects(world, jsondata, jsondata["objects"].(map[string]interface{}))...)
}
Beispiel #4
0
func parseGeometry(world *scene.Scene, jsondata map[string]interface{}, geometry_id string) (geometry *objects.Geometry) {
	log.Println("Parsing Json Geometry")
	embeds := jsondata["embeds"].(map[string]interface{})
	geometrydata := jsondata["geometries"].(map[string]interface{})[geometry_id].(map[string]interface{})

	geometry = new(objects.Geometry)
	geometry.ID = geometry_id
	if geometrydata["type"].(string) == "embedded" {
		embed := embeds[geometrydata["id"].(string)].(map[string]interface{})

		// Parse metadata
		geometry.Metadata.Vertices = int32(embed["metadata"].(map[string]interface{})["vertices"].(float64))
		geometry.Metadata.Normals = int32(embed["metadata"].(map[string]interface{})["normals"].(float64))
		geometry.Metadata.Colors = int32(embed["metadata"].(map[string]interface{})["colors"].(float64))
		geometry.Metadata.Faces = int32(embed["metadata"].(map[string]interface{})["faces"].(float64))

		// Parse bounding box
		geometry.BB.Min.X = float32(embed["boundingBox"].(map[string]interface{})["min"].([]interface{})[0].(float64))
		geometry.BB.Min.Y = float32(embed["boundingBox"].(map[string]interface{})["min"].([]interface{})[1].(float64))
		geometry.BB.Min.Z = float32(embed["boundingBox"].(map[string]interface{})["min"].([]interface{})[2].(float64))
		geometry.BB.Max.X = float32(embed["boundingBox"].(map[string]interface{})["max"].([]interface{})[0].(float64))
		geometry.BB.Max.Y = float32(embed["boundingBox"].(map[string]interface{})["max"].([]interface{})[1].(float64))
		geometry.BB.Max.Z = float32(embed["boundingBox"].(map[string]interface{})["max"].([]interface{})[2].(float64))

		geometry.Scale = float32(embed["scale"].(float64))
		vertices := embed["vertices"].([]interface{})
		for i := 0; i < len(vertices); {
			v := vertex.NewVertex(float32(vertices[i].(float64)), float32(vertices[i+1].(float64)), float32(vertices[i+2].(float64)))
			i += 3
			world.Vertices = append(world.Vertices, *v)
			geometry.Vertices = append(geometry.Vertices, &world.Vertices[len(world.Vertices)-1])
		}

		normals := embed["normals"].([]interface{})
		for i := 0; i < len(normals); {
			v := vertex.NewNormal(float32(normals[i].(float64)), float32(normals[i+1].(float64)), float32(normals[i+2].(float64)))
			i += 3
			world.Normals = append(world.Normals, *v)
			geometry.Normals = append(geometry.Normals, &world.Normals[len(world.Normals)-1])
		}

		faces := embed["faces"].([]interface{})
		for i := 0; i < len(faces); {
			mask := uint32(faces[i].(float64))
			i++

			// is not triangle?
			if isBitSet(mask, 0) {
				log.Fatalln("Quads are not supported")
			}
			tri := triangle.Triangle{Vertices: [3]*vertex.Vertex{&world.Vertices[int32(faces[i].(float64))], &world.Vertices[int32(faces[i+1].(float64))], &world.Vertices[int32(faces[i+2].(float64))]}}
			i += 3
			// has face material
			if isBitSet(mask, 1) {
				log.Println("Ignoring face material, material defined in the geometry json")
				i++
			}

			// has face uv
			if isBitSet(mask, 2) {
				log.Fatalln("Face UVs are not supported")
				i++
			}

			// has face vertex uv
			if isBitSet(mask, 3) {
				log.Fatalln("Face vertex UVs are not supported")
				i += 3
			}

			// has face normals
			if isBitSet(mask, 4) {
				log.Fatalln("Face normals are not supported")
				i++
			}

			// has face vertex normals
			if isBitSet(mask, 5) {
				tri.Normals = [3]*vertex.Normal{&world.Normals[int32(faces[i].(float64))], &world.Normals[int32(faces[i+1].(float64))], &world.Normals[int32(faces[i+2].(float64))]}
				i += 3
			}

			// has face color
			if isBitSet(mask, 6) {
				log.Fatalln("Face colors are not supported")
				i++
			}

			if isBitSet(mask, 7) {
				log.Fatalln("Face vertex colors are not supported")
				i += 3
			}

			world.Triangles = append(world.Triangles, tri)
			log.Println(tri)
		}
	} else {
		log.Panicln("I don't know what to do with non-embedded geometry types!")
	}

	return
}