Error ResourceInteractiveLoaderBinary::poll(){
if (error!=OK)
return error;
int s = stage;
if (s<external_resources.size()) {
RES res = ResourceLoader::load(external_resources[s].path,external_resources[s].type);
if (res.is_null()) {
if (!ResourceLoader::get_abort_on_missing_resources()) {
ResourceLoader::notify_load_error("Resource Not Found: "+external_resources[s].path);
} else {
error=ERR_FILE_CORRUPT;
ERR_EXPLAIN("Can't load dependency: "+external_resources[s].path);
ERR_FAIL_V(error);
}
} else {
resource_cache.push_back(res);
}
stage++;
return OK;
}
s-=external_resources.size();
if (s>=internal_resources.size()) {
error=ERR_BUG;
ERR_FAIL_COND_V(s>=internal_resources.size(),error);
}
bool main = s==(internal_resources.size()-1);
//maybe it is loaded already
String path;
if (!main) {
path=internal_resources[s].path;
if (path.begins_with("local://"))
path=path.replace("local://",res_path+"::");
if (ResourceCache::has(path)) {
//already loaded, don't do anything
stage++;
error=OK;
return error;
}
} else {
path=res_path;
}
uint64_t offset = internal_resources[s].offset;
f->seek(offset);
String t = get_unicode_string();
Object *obj = ObjectTypeDB::instance(t);
if (!obj) {
error=ERR_FILE_CORRUPT;
ERR_EXPLAIN(local_path+":Resource of unrecognized type in file: "+t);
}
ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT);
Resource *r = obj->cast_to<Resource>();
if (!r) {
error=ERR_FILE_CORRUPT;
memdelete(obj); //bye
ERR_EXPLAIN(local_path+":Resoucre type in resource field not a resource, type is: "+obj->get_type());
ERR_FAIL_COND_V(!r,ERR_FILE_CORRUPT);
}
RES res = RES( r );
r->set_path(path);
int pc = f->get_32();
//set properties
for(int i=0;i<pc;i++) {
uint32_t name_idx = f->get_32();
if (name_idx>=(uint32_t)string_map.size()) {
//.........这里部分代码省略.........
Array VoxelMesher::build(const VoxelBuffer &buffer, unsigned int channel, Vector3i min, Vector3i max) {
uint64_t time_before = OS::get_singleton()->get_ticks_usec();
ERR_FAIL_COND_V(_library.is_null(), Array());
ERR_FAIL_COND_V(channel >= VoxelBuffer::MAX_CHANNELS, Array());
const VoxelLibrary &library = **_library;
for (unsigned int i = 0; i < MAX_MATERIALS; ++i) {
Arrays &a = _arrays[i];
a.positions.clear();
a.normals.clear();
a.uvs.clear();
a.colors.clear();
a.indices.clear();
}
float baked_occlusion_darkness;
if (_bake_occlusion)
baked_occlusion_darkness = _baked_occlusion_darkness / 3.0;
// The technique is Culled faces.
// Could be improved with greedy meshing: https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/
// However I don't feel it's worth it yet:
// - Not so much gain for organic worlds with lots of texture variations
// - Works well with cubes but not with any shape
// - Slower
// => Could be implemented in a separate class?
// Data must be padded, hence the off-by-one
Vector3i::sort_min_max(min, max);
const Vector3i pad(1, 1, 1);
min.clamp_to(pad, max);
max.clamp_to(min, buffer.get_size() - pad);
int index_offset = 0;
// Iterate 3D padded data to extract voxel faces.
// This is the most intensive job in this class, so all required data should be as fit as possible.
// The buffer we receive MUST be dense (i.e not compressed, and channels allocated).
// That means we can use raw pointers to voxel data inside instead of using the higher-level getters,
// and then save a lot of time.
uint8_t *type_buffer = buffer.get_channel_raw(Voxel::CHANNEL_TYPE);
// _
// | \
// /\ \\
// / /|\\\
// | |\ \\\
// | \_\ \\|
// | | )
// \ | |
// \ /
CRASH_COND(type_buffer == NULL);
//CRASH_COND(memarr_len(type_buffer) != buffer.get_volume() * sizeof(uint8_t));
// Build lookup tables so to speed up voxel access.
// These are values to add to an address in order to get given neighbor.
int row_size = buffer.get_size().y;
int deck_size = buffer.get_size().x * row_size;
int side_neighbor_lut[Cube::SIDE_COUNT];
side_neighbor_lut[Cube::SIDE_LEFT] = row_size;
side_neighbor_lut[Cube::SIDE_RIGHT] = -row_size;
side_neighbor_lut[Cube::SIDE_BACK] = -deck_size;
side_neighbor_lut[Cube::SIDE_FRONT] = deck_size;
side_neighbor_lut[Cube::SIDE_BOTTOM] = -1;
side_neighbor_lut[Cube::SIDE_TOP] = 1;
int edge_neighbor_lut[Cube::EDGE_COUNT];
edge_neighbor_lut[Cube::EDGE_BOTTOM_BACK] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_BACK];
edge_neighbor_lut[Cube::EDGE_BOTTOM_FRONT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_FRONT];
edge_neighbor_lut[Cube::EDGE_BOTTOM_LEFT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_LEFT];
edge_neighbor_lut[Cube::EDGE_BOTTOM_RIGHT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_RIGHT];
edge_neighbor_lut[Cube::EDGE_BACK_LEFT] = side_neighbor_lut[Cube::SIDE_BACK] + side_neighbor_lut[Cube::SIDE_LEFT];
edge_neighbor_lut[Cube::EDGE_BACK_RIGHT] = side_neighbor_lut[Cube::SIDE_BACK] + side_neighbor_lut[Cube::SIDE_RIGHT];
edge_neighbor_lut[Cube::EDGE_FRONT_LEFT] = side_neighbor_lut[Cube::SIDE_FRONT] + side_neighbor_lut[Cube::SIDE_LEFT];
edge_neighbor_lut[Cube::EDGE_FRONT_RIGHT] = side_neighbor_lut[Cube::SIDE_FRONT] + side_neighbor_lut[Cube::SIDE_RIGHT];
edge_neighbor_lut[Cube::EDGE_TOP_BACK] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_BACK];
edge_neighbor_lut[Cube::EDGE_TOP_FRONT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_FRONT];
edge_neighbor_lut[Cube::EDGE_TOP_LEFT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_LEFT];
edge_neighbor_lut[Cube::EDGE_TOP_RIGHT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_RIGHT];
int corner_neighbor_lut[Cube::CORNER_COUNT];
corner_neighbor_lut[Cube::CORNER_BOTTOM_BACK_LEFT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_BACK] + side_neighbor_lut[Cube::SIDE_LEFT];
corner_neighbor_lut[Cube::CORNER_BOTTOM_BACK_RIGHT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_BACK] + side_neighbor_lut[Cube::SIDE_RIGHT];
corner_neighbor_lut[Cube::CORNER_BOTTOM_FRONT_RIGHT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_FRONT] + side_neighbor_lut[Cube::SIDE_RIGHT];
corner_neighbor_lut[Cube::CORNER_BOTTOM_FRONT_LEFT] = side_neighbor_lut[Cube::SIDE_BOTTOM] + side_neighbor_lut[Cube::SIDE_FRONT] + side_neighbor_lut[Cube::SIDE_LEFT];
corner_neighbor_lut[Cube::CORNER_TOP_BACK_LEFT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_BACK] + side_neighbor_lut[Cube::SIDE_LEFT];
corner_neighbor_lut[Cube::CORNER_TOP_BACK_RIGHT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_BACK] + side_neighbor_lut[Cube::SIDE_RIGHT];
corner_neighbor_lut[Cube::CORNER_TOP_FRONT_RIGHT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_FRONT] + side_neighbor_lut[Cube::SIDE_RIGHT];
corner_neighbor_lut[Cube::CORNER_TOP_FRONT_LEFT] = side_neighbor_lut[Cube::SIDE_TOP] + side_neighbor_lut[Cube::SIDE_FRONT] + side_neighbor_lut[Cube::SIDE_LEFT];
uint64_t time_prep = OS::get_singleton()->get_ticks_usec() - time_before;
time_before = OS::get_singleton()->get_ticks_usec();
//.........这里部分代码省略.........
Error HTTPClient::poll() {
switch (status) {
case STATUS_RESOLVING: {
ERR_FAIL_COND_V(resolving == IP::RESOLVER_INVALID_ID, ERR_BUG);
IP::ResolverStatus rstatus = IP::get_singleton()->get_resolve_item_status(resolving);
switch (rstatus) {
case IP::RESOLVER_STATUS_WAITING:
return OK; // Still resolving
case IP::RESOLVER_STATUS_DONE: {
IP_Address host = IP::get_singleton()->get_resolve_item_address(resolving);
Error err = tcp_connection->connect_to_host(host, conn_port);
IP::get_singleton()->erase_resolve_item(resolving);
resolving = IP::RESOLVER_INVALID_ID;
if (err) {
status = STATUS_CANT_CONNECT;
return err;
}
status = STATUS_CONNECTING;
} break;
case IP::RESOLVER_STATUS_NONE:
case IP::RESOLVER_STATUS_ERROR: {
IP::get_singleton()->erase_resolve_item(resolving);
resolving = IP::RESOLVER_INVALID_ID;
close();
status = STATUS_CANT_RESOLVE;
return ERR_CANT_RESOLVE;
} break;
}
} break;
case STATUS_CONNECTING: {
StreamPeerTCP::Status s = tcp_connection->get_status();
switch (s) {
case StreamPeerTCP::STATUS_CONNECTING: {
return OK;
} break;
case StreamPeerTCP::STATUS_CONNECTED: {
if (ssl) {
Ref<StreamPeerSSL> ssl;
if (!handshaking) {
// Connect the StreamPeerSSL and start handshaking
ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
ssl->set_blocking_handshake_enabled(false);
Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
if (err != OK) {
close();
status = STATUS_SSL_HANDSHAKE_ERROR;
return ERR_CANT_CONNECT;
}
connection = ssl;
handshaking = true;
} else {
// We are already handshaking, which means we can use your already active SSL connection
ssl = static_cast<Ref<StreamPeerSSL> >(connection);
ssl->poll(); // Try to finish the handshake
}
if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
// Handshake has been successful
handshaking = false;
status = STATUS_CONNECTED;
return OK;
} else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
// Handshake has failed
close();
status = STATUS_SSL_HANDSHAKE_ERROR;
return ERR_CANT_CONNECT;
}
// ... we will need to poll more for handshake to finish
} else {
status = STATUS_CONNECTED;
}
return OK;
} break;
case StreamPeerTCP::STATUS_ERROR:
case StreamPeerTCP::STATUS_NONE: {
close();
status = STATUS_CANT_CONNECT;
return ERR_CANT_CONNECT;
} break;
}
} break;
case STATUS_BODY:
case STATUS_CONNECTED: {
// Check if we are still connected
if (ssl) {
Ref<StreamPeerSSL> tmp = connection;
tmp->poll();
if (tmp->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
status = STATUS_CONNECTION_ERROR;
return ERR_CONNECTION_ERROR;
//.........这里部分代码省略.........
请发表评论