void Model::fix_vert() { return; if (m_meshes.size() == 1 && m_meshes[0]->isPlane()) { return; } glm::vec3 vmin = glm::vec3(BIG_NUM, BIG_NUM, BIG_NUM), vmax = glm::vec3(0, 0, 0); for (unsigned i = 0; i < m_meshes.size(); i++) { glm::vec3 lvmin, lvmax; m_meshes[i]->getMinMax(lvmin, lvmax); if (VLess(lvmin, vmin)) { vmin = lvmin; } if (VLess(vmax, lvmax)) { vmax = lvmax; } } glm::vec3 tmpv = 0.5f * (vmax - vmin); for (unsigned i = 0; i < m_meshes.size(); i++) { m_meshes[i]->ReTrans(tmpv); } for (unsigned i = 0; i < m_meshes.size(); i++) { m_meshes[i]->ReScale( 1.0f / glm::length(vmax - vmin)); // m_meshes[i]->ReScale(0.9f); } }
static VM *execute(VM *vm) { int maxInstructions = 100; while (maxInstructions--) { int i = *vm->ip; int arg = i >> 8; if (DEBUG_TRACE) { traceLine(vm, (int)(vm->ip - vmBytecode)); fflush(stdout); } vm->ip++; switch ((Instruction)(i & 0xff)) { case OP_NULL: storeValue(vm, vm->bp, arg, VNull); break; case OP_TRUE: storeValue(vm, vm->bp, arg, VTrue); break; case OP_FALSE: storeValue(vm, vm->bp, arg, VFalse); break; case OP_EMPTY_LIST: storeValue(vm, vm->bp, arg, VEmptyList); break; case OP_LIST: { vref result; vref *array; vref *write; assert(arg); array = VCreateArray((size_t)arg); for (write = array; arg--; write++) { vref value = loadValue(vm, vm->bp, *vm->ip++); if (value == VFuture) { vm->ip += arg; VAbortArray(array); result = VFuture; goto storeList; } *write = value; assert(HeapGetObjectType(*write) != TYPE_FUTURE); } result = VFinishArray(array); storeList: storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_FILELIST: { vref string = refFromInt(arg); vref result; if (string == VFuture) { result = VFuture; } else { result = VCreateFilelistGlob(VGetString(string), VStringLength(string)); } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_STORE_CONSTANT: storeValue(vm, vm->bp, arg, refFromInt(*vm->ip++)); break; case OP_COPY: storeValue(vm, vm->bp, *vm->ip++, loadValue(vm, vm->bp, arg)); break; case OP_NOT: storeValue(vm, vm->bp, *vm->ip++, VNot(loadValue(vm, vm->bp, arg))); break; case OP_NEG: { vref result = VNeg(vm, loadValue(vm, vm->bp, arg)); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_INV: { vref result = VInv(vm, loadValue(vm, vm->bp, arg)); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_ITER_NEXT: { vref collection = loadValue(vm, vm->bp, *vm->ip++); int indexVariable = *vm->ip++; vref index = loadValue(vm, vm->bp, indexVariable); vref step = loadValue(vm, vm->bp, *vm->ip++); if (index == VFuture || step == VFuture) { index = VFuture; storeValue(vm, vm->bp, indexVariable, index); goto iterNextFuture; } else { index = VAdd(vm, index, step); storeValue(vm, vm->bp, indexVariable, index); } if (collection == VFuture) { iterNextFuture: assert(0); } switch (VGetBool(VValidIndex(vm, collection, index))) { case TRUTHY: storeValue(vm, vm->bp, *vm->ip++, VIndexedAccess(vm, collection, index)); break; case FALSY: vm->ip += arg - 2; break; case FUTURE: unreachable; } break; } case OP_EQUALS: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VEquals(value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_NOT_EQUALS: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VEquals(value1, value2); if (!result) { return vm; } switch (VGetBool(result)) { case TRUTHY: result = VFalse; break; case FALSY: result = VTrue; break; case FUTURE: break; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_LESS_EQUALS: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VLessEquals(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_GREATER_EQUALS: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VLessEquals(vm, value2, value1); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_LESS: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VLess(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_GREATER: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VLess(vm, value2, value1); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_ADD: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VAdd(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_SUB: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VSub(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_MUL: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VMul(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_DIV: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VDiv(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_REM: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VRem(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_CONCAT_LIST: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VConcat(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_CONCAT_STRING: { vref result; assert(!IVSize(&temp)); for (i = 0; i < arg; i++) { IVAdd(&temp, intFromRef(loadValue(vm, vm->bp, *vm->ip++))); } result = VConcatString((size_t)arg, (vref*)IVGetWritePointer(&temp, 0)); storeValue(vm, vm->bp, *vm->ip++, result); IVSetSize(&temp, 0); break; } case OP_INDEXED_ACCESS: { vref collection = loadValue(vm, vm->bp, arg); vref index = loadValue(vm, vm->bp, *vm->ip++); vref result = VIndexedAccess(vm, collection, index); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_RANGE: { vref value1 = loadValue(vm, vm->bp, arg); vref value2 = loadValue(vm, vm->bp, *vm->ip++); vref result = VRange(vm, value1, value2); if (!result) { return vm; } storeValue(vm, vm->bp, *vm->ip++, result); break; } case OP_JUMP: vm->ip += arg + 1; break; case OP_BRANCH_TRUE: { vref value = loadValue(vm, vm->bp, *vm->ip++); VBool b = VGetBool(value); vm->base.clonePoints++; if (vm->child && vm->base.clonePoints >= vm->child->clonePoints) { if (vm->base.clonePoints > vm->child->clonePoints) { VMDispose(vm->child); vm->child = null; goto branchTrueNoChild; } assert(!vm->child->fullVM); if (b == FUTURE) { VMReplaceCloneBranch(vm, vm->ip + arg); } else { uint keepChild; if (b == FALSY) { keepChild = 0; } else { vm->ip += arg; keepChild = 1; } vm->child = VMDisposeBranch((VMBranch*)vm->child, keepChild); } } else { branchTrueNoChild: switch (b) { case FALSY: break; case FUTURE: assert(!vm->child); VMCloneBranch(vm, vm->ip); /* fallthrough */ case TRUTHY: vm->ip += arg; break; } } break; } case OP_BRANCH_FALSE: { vref value = loadValue(vm, vm->bp, *vm->ip++); VBool b = VGetBool(value); vm->base.clonePoints++; if (vm->child && vm->base.clonePoints >= vm->child->clonePoints) { if (vm->base.clonePoints > vm->child->clonePoints) { VMDispose(vm->child); vm->child = null; goto branchFalseNoChild; } assert(!vm->child->fullVM); if (b == FUTURE) { VMReplaceCloneBranch(vm, vm->ip); vm->ip += arg; } else { uint keepChild; if (b == FALSY) { vm->ip += arg; keepChild = 0; } else { keepChild = 1; } vm->child = VMDisposeBranch((VMBranch*)vm->child, keepChild); } } else { branchFalseNoChild: switch (b) { case TRUTHY: break; case FUTURE: assert(!vm->child); VMCloneBranch(vm, vm->ip); /* fallthrough */ case FALSY: vm->ip += arg; break; } } break; } case OP_RETURN: assert(IVSize(&vm->callStack)); popStackFrame(vm, &vm->ip, &vm->bp, (uint)arg); break; case OP_RETURN_VOID: if (!IVSize(&vm->callStack)) { vm->base.clonePoints++; VMHalt(vm, 0); return vm; } popStackFrame(vm, &vm->ip, &vm->bp, 0); break; case OP_INVOKE: { vref *values; int function = *vm->ip++; values = (vref*)IVGetAppendPointer(&vm->stack, (size_t)arg); for (i = 0; i < arg; i++) { *values++ = loadValue(vm, vm->bp, *vm->ip++); } IVAdd(&vm->callStack, (int)(vm->ip - vmBytecode)); IVAdd(&vm->callStack, vm->bp); initStackFrame(vm, &vm->ip, &vm->bp, function, (uint)arg); break; } case OP_INVOKE_NATIVE: { nativefunctionref nativeFunction = refFromInt(arg); vref value; int storeAt; assert(!vm->job); vm->base.clonePoints++; if (vm->child && vm->base.clonePoints >= vm->child->clonePoints) { VM *child = (VM*)vm->child; assert(vm->child->fullVM); VMReplaceChild(vm, child); } value = NativeInvoke(vm, nativeFunction); if (vm->idle) { return vm; } storeAt = *vm->ip++; storeValue(vm, vm->bp, storeAt, value); if (vm->job) { vm->job->storeAt = storeAt; vm->idle = true; /* TODO: Activate speculative execution */ JobExecute(vm->job); if (unlikely(vm->failMessage)) { return vm; } /* vm = VMClone(vm, vm->ip); */ } break; } case OP_FUNCTION: case OP_FUNCTION_UNLINKED: case OP_LOAD_FIELD: case OP_STORE_FIELD: case OP_ITER_NEXT_INDEXED: case OP_JUMPTARGET: case OP_JUMP_INDEXED: case OP_BRANCH_TRUE_INDEXED: case OP_BRANCH_FALSE_INDEXED: case OP_INVOKE_UNLINKED: case OP_UNKNOWN_VALUE: case OP_FILE: case OP_LINE: case OP_ERROR: default: unreachable; } } return vm; }
bool Model::IntersectRay(const SRay &m_ray, glm::vec3 &out_point, glm::vec3 &out_norm, glm::vec2 &texcoord, glm::vec3 &coutput, bool intersection_only) { glm::vec3 dmin = glm::vec3(BIG_NUM, BIG_NUM, BIG_NUM); glm::vec2 mintex; glm::vec3 normal; /*SRay my_ray; my_ray.level_id = m_ray.level_id; my_ray.m_dir = ApplyMat4(Tdirinv, m_ray.m_dir); my_ray.m_start = ApplyMat4(Tinv , m_ray.m_start); */ SRay my_ray = convert_ray(m_ray); int id = -1; for (unsigned i = 0; i < m_meshes.size(); i++) { glm::vec3 res; glm::vec2 tex; glm::vec3 norm_vec; // if (m_meshes[i]->IntersectRay(my_ray, res, norm_vec, tex)) { if (VLess(res - m_ray.m_start, dmin - m_ray.m_start)) { dmin = res; mintex = tex; normal = norm_vec; id = i; } } } if (id == -1) { return false; } if (intersection_only) { return true; } out_point = ApplyMat4(T, dmin); out_norm = ApplyMat4(Tdir, normal); texcoord = mintex; // glm::vec3 light_pos = m_scene.get_LigthPos(); // glm::vec3 tmnormal = ApplyMat4(Tdir, normal); // if (glm::dot(tmnormal, light_pos - out_point) < 0) { // normal = -normal; // } // light_pos = ApplyMat4(T, light_pos); // glm::vec3 ps_color = m_textures[id]->getPixel(mintex[0], mintex[1]); // glm::vec3 mycolor = Phong(dmin, normal, light_pos, my_ray.m_start, ps_color); // /*float cos_psi = glm::dot(glm::normalize(light_pos - dmin), glm::normalize(normal)); // mycolor = ps_color * cos_psi; // if (cos_psi < 0) { // mycolor = shade_coeff; // }*/ // //glm::vec3 mycolor = ps_color; // float xa = 1.0f; // float ya = coeff_spec; // if ( m_scene.LightTrace(out_point)) { // //fprintf(stderr, "Can see light\n"); // xa = coeff_diff; // } // glm::vec3 specc = glm::vec3(0, 0, 0); // if (m_type != DIFFUSE_MODEL && m_ray.level_id < MAX_DEPTH) { // SRay ray2; // ray2.level_id = m_ray.level_id + 1; // ray2.m_start = out_point; // glm::vec3 tnorm = ApplyMat4(Tdir, normal); // ray2.m_dir = glm::reflect(glm::normalize(out_point - m_ray.m_start), // tnorm); // specc = m_scene.TraceRay(ray2); // } // coutput = xa * mycolor + ya * specc; return true; }